/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "libzlang_stdtypes.h"

extern TLS int				_zlang_recursive_depth ;

struct ZlangDirectProperty_string
{
	char		*buf ;
	int32_t		buf_size ;
	int32_t		buf_len ;
} ;

#define ZLANG_STRING_BUFFER_MIN_INCREASE_SIZE	8

#define ZLANG_STRING_ADD_TERMINATOR(_obj_direct_prop_)		{if((_obj_direct_prop_)->buf) (_obj_direct_prop_)->buf[(_obj_direct_prop_)->buf_len]='\0';}

static int PrepareBuffer( struct ZlangRuntime *rt , struct ZlangDirectProperty_string *obj_direct_prop , int32_t fill_len )
{
	int32_t		dd_len ;
	
	if( fill_len <= 0 )
		return 0;
	
	dd_len = (obj_direct_prop->buf_size-1-obj_direct_prop->buf_len) - fill_len ;
	if( obj_direct_prop->buf == NULL || dd_len < 0 )
	{
		char		*new_buf = NULL ;
		int32_t		new_buf_size ;
		
		/*
		TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "before ZLREALLOC : buf[%p] buf_size[%"PRIi32"] buf_len[%"PRIi32"] , remain_len[%"PRIi32"]-fill_len[%"PRIi32"]=[%"PRIi32"]" , obj_direct_prop->buf , obj_direct_prop->buf_size , obj_direct_prop->buf_len , obj_direct_prop->buf_size-1-obj_direct_prop->buf_len , fill_len , dd_len )
		*/
		dd_len = -dd_len ;
		
		if( obj_direct_prop->buf_size == 0 )
			obj_direct_prop->buf_size = 1 ;
		if( dd_len < ZLANG_STRING_BUFFER_MIN_INCREASE_SIZE )
			new_buf_size = obj_direct_prop->buf_size + ZLANG_STRING_BUFFER_MIN_INCREASE_SIZE ;
		else
			new_buf_size = obj_direct_prop->buf_size + dd_len ;
		/*
		TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "buf_size[%"PRIi32"] new_buf_size[%"PRIi32"]" , obj_direct_prop->buf_size , new_buf_size )
		*/
		new_buf = ZLREALLOC( obj_direct_prop->buf , new_buf_size ) ;
		if( new_buf == NULL )
		{
			SET_RUNTIME_ERROR( rt , RUNTIME_ERROR , ZLANG_ERROR_ALLOC , "alloc memory for formatting" )
			return ZLANG_ERROR_ALLOC;
		}
		obj_direct_prop->buf = new_buf ;
		obj_direct_prop->buf_size = new_buf_size ;
		memset( obj_direct_prop->buf+obj_direct_prop->buf_len , 0x00 , obj_direct_prop->buf_size-obj_direct_prop->buf_len );
		/*
		TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "after ZLREALLOC : buf[%p] buf_size[%"PRIi32"] buf_len[%"PRIi32"]" , obj_direct_prop->buf , obj_direct_prop->buf_size , obj_direct_prop->buf_len )
		*/
	}
	
	return 0;
}

static int ExpandEnvVariables( struct ZlangRuntime *rt , struct ZlangDirectProperty_string *obj_direct_prop )
{
	char		*p1 = NULL ;
	int32_t		p1_offset ;
	char		*p2 = NULL ;
	int32_t		p2_offset ;
	int32_t		env_name_len ;
	char		env_name[ 64 ] ;
	char		*env_value = NULL ;
	int32_t		env_value_len ;
	int32_t		append_len ;
	int		nret = 0 ;
	
	ZLANG_STRING_ADD_TERMINATOR( obj_direct_prop )
	
	p2 = obj_direct_prop->buf ;
	for( ; ; )
	{
		p1 = strstr( p2 , "${" ) ;
		if( p1 == NULL )
			break;
		p1_offset = p1 - obj_direct_prop->buf ;
		
		p2 = strchr( p1+2 , '}' ) ;
		if( p2 == NULL )
			return -1;
		env_name_len = p2 - (p1+2) ;
		if( env_name_len == 0 || env_name_len > sizeof(env_name)-1 )
			return -2;
		p2_offset = p2 - obj_direct_prop->buf ;
		
		memcpy( env_name , p1+2 , env_name_len ); env_name[env_name_len] = '\0' ;
		env_value = getenv( env_name ) ;
		if( env_value == NULL )
			return -3;
		env_value_len = strlen(env_value) ;
		
		append_len = env_value_len - (p2-p1+1) ;
		nret = PrepareBuffer( rt , obj_direct_prop , append_len ) ;
		if( nret )
			return -4;
		
		if( append_len )
		{
			obj_direct_prop->buf_len += append_len ;
			memmove( obj_direct_prop->buf+p1_offset+env_value_len , obj_direct_prop->buf+p2_offset+1 , strlen(obj_direct_prop->buf+p2_offset+1) );
			ZLANG_STRING_ADD_TERMINATOR( obj_direct_prop )
		}
		memcpy( obj_direct_prop->buf+p1_offset , env_value , env_value_len );
		
		p2 = obj_direct_prop->buf + p1_offset ;
	}
	
	return 0;
}

ZlangInvokeFunction ZlangInvokeFunction_string_Append_string;
int ZlangInvokeFunction_string_Append_string( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	struct ZlangDirectProperty_string	*obj_direct_prop = GetObjectDirectProperty(obj) ;
	struct ZlangObject			*in1 = GetInputParameterInLocalObjectStack(rt,1) ;
	char					*buf2 = NULL ;
	int32_t					buf2_len ;
	int					nret = 0 ;
	
	CallRuntimeFunction_string_GetStringValue( rt , in1 , & buf2 , & buf2_len );
	
	if( obj_direct_prop->buf == NULL )
	{
		nret = FromCharPtr( rt , obj , buf2 , buf2_len ) ;
		if( nret )
		{
			TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "FromCharPtr failed[%d]" , nret )
			return nret;
		}
		
		return 0;
	}
	
	nret = PrepareBuffer( rt , obj_direct_prop , buf2_len ) ;
	if( nret )
	{
		TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "PrepareBuffer failed[%d] , fill_len[%"PRIi32"" , nret , buf2_len )
		return nret;
	}
	
	memcpy( obj_direct_prop->buf+obj_direct_prop->buf_len , buf2 , buf2_len );
	obj_direct_prop->buf_len += buf2_len ;
	obj_direct_prop->buf[obj_direct_prop->buf_len] = '\0' ;
	
	return 0;
}

#if 0
ZlangInvokeFunction ZlangInvokeFunction_string_CharAt_int;
int ZlangInvokeFunction_string_CharAt_int( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	struct ZlangDirectProperty_string	*obj_direct_prop = GetObjectDirectProperty(obj) ;
	struct ZlangObject			*in1 = GetInputParameterInLocalObjectStack(rt,1) ;
	struct ZlangObject			*out1 = GetOutputParameterInLocalObjectStack(rt,1) ;
	int32_t					pos ;
	int					nret = 0 ;
	
	CallRuntimeFunction_int_GetIntValue( rt , in1 , & pos );
	
	if( pos <= 0 )
	{
		UnreferObject( rt , obj );
	}
	else if( pos > obj_direct_prop->buf_len )
	{
		UnreferObject( rt , obj );
	}
	else if( obj_direct_prop->buf )
	{
		nret = FromCharPtr( rt , out1 , obj_direct_prop->buf+(pos-1) , 1 ) ;
		if( nret )
		{
			TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "FromCharPtr failed[%d]" , nret )
			return nret;
		}
	}
	
	return 0;
}
#endif

ZlangInvokeFunction ZlangInvokeFunction_string_Delete_int_int;
int ZlangInvokeFunction_string_Delete_int_int( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	struct ZlangDirectProperty_string	*obj_direct_prop = GetObjectDirectProperty(obj) ;
	struct ZlangObject			*in1 = GetInputParameterInLocalObjectStack(rt,1) ;
	struct ZlangObject			*in2 = GetInputParameterInLocalObjectStack(rt,2) ;
	int32_t					start_pos ;
	int32_t					end_pos ;
	
	CallRuntimeFunction_int_GetIntValue( rt , in1 , & start_pos );
	CallRuntimeFunction_int_GetIntValue( rt , in2 , & end_pos );
	
	if( obj_direct_prop->buf == NULL )
	{
		return 0;
	}
	
	if( end_pos < start_pos )
	{
		return 0;
	}
	
	if( start_pos < 1 )
		start_pos = 1 ;
	if( end_pos > obj_direct_prop->buf_len )
		end_pos = obj_direct_prop->buf_len ;
	if( end_pos == obj_direct_prop->buf_len )
	{
		obj_direct_prop->buf_len = start_pos-1 ;
		obj_direct_prop->buf[obj_direct_prop->buf_len] = '\0' ;
	}
	else
	{
		memmove( obj_direct_prop->buf+(start_pos-1) , obj_direct_prop->buf+end_pos , obj_direct_prop->buf_len-end_pos );
		obj_direct_prop->buf_len -= end_pos-start_pos+1 ;
		obj_direct_prop->buf[obj_direct_prop->buf_len] = '\0' ;
	}
	
	return 0;
}

ZlangInvokeFunction ZlangInvokeFunction_string_EndWith_string;
int ZlangInvokeFunction_string_EndWith_string( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	struct ZlangDirectProperty_string	*obj_direct_prop = GetObjectDirectProperty(obj) ;
	struct ZlangObject			*in1 = GetInputParameterInLocalObjectStack(rt,1) ;
	struct ZlangObject			*out1 = GetOutputParameterInLocalObjectStack(rt,1) ;
	char					*buf2 = NULL ;
	int32_t					buf2_len ;
	
	CallRuntimeFunction_string_GetStringValue( rt , in1 , & buf2 , & buf2_len );
	
	if( obj_direct_prop->buf == NULL )
	{
		CallRuntimeFunction_bool_SetBoolValue( rt , out1 , FALSE );
		return 0;
	}
	
	if( obj_direct_prop->buf_len < buf2_len )
	{
		CallRuntimeFunction_bool_SetBoolValue( rt , out1 , FALSE );
		return 0;
	}
	
	if( strncmp( obj_direct_prop->buf + (obj_direct_prop->buf_len-buf2_len) , buf2 , buf2_len ) == 0 )
		CallRuntimeFunction_bool_SetBoolValue( rt , out1 , TRUE );
	else
		CallRuntimeFunction_bool_SetBoolValue( rt , out1 , FALSE );
	return 0;
}

ZlangInvokeFunction ZlangInvokeFunction_string_EndCaseWith_string;
int ZlangInvokeFunction_string_EndCaseWith_string( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	struct ZlangDirectProperty_string	*obj_direct_prop = GetObjectDirectProperty(obj) ;
	struct ZlangObject			*in1 = GetInputParameterInLocalObjectStack(rt,1) ;
	struct ZlangObject			*out1 = GetOutputParameterInLocalObjectStack(rt,1) ;
	char					*buf2 = NULL ;
	int32_t					buf2_len ;
	
	CallRuntimeFunction_string_GetStringValue( rt , in1 , & buf2 , & buf2_len );
	
	if( obj_direct_prop->buf == NULL )
	{
		CallRuntimeFunction_bool_SetBoolValue( rt , out1 , FALSE );
		return 0;
	}
	
	if( obj_direct_prop->buf_len < buf2_len )
	{
		CallRuntimeFunction_bool_SetBoolValue( rt , out1 , FALSE );
		return 0;
	}
	
	if( strncasecmp( obj_direct_prop->buf + (obj_direct_prop->buf_len-buf2_len) , buf2 , buf2_len ) == 0 )
		CallRuntimeFunction_bool_SetBoolValue( rt , out1 , TRUE );
	else
		CallRuntimeFunction_bool_SetBoolValue( rt , out1 , FALSE );
	return 0;
}

ZlangInvokeFunction ZlangInvokeFunction_string_EqualsIgnoreCase_string;
int ZlangInvokeFunction_string_EqualsIgnoreCase_string( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	struct ZlangDirectProperty_string	*obj_direct_prop = GetObjectDirectProperty(obj) ;
	struct ZlangObject			*in1 = GetInputParameterInLocalObjectStack(rt,1) ;
	struct ZlangObject			*out1 = GetOutputParameterInLocalObjectStack(rt,1) ;
	char					*buf2 = NULL ;
	
	CallRuntimeFunction_string_GetStringValue( rt , in1 , & buf2 , NULL );
	
	if( obj_direct_prop->buf == NULL )
	{
		CallRuntimeFunction_bool_SetBoolValue( rt , out1 , FALSE );
		return 0;
	}
	
	if( strcasecmp( obj_direct_prop->buf , buf2 ) == 0 )
		CallRuntimeFunction_bool_SetBoolValue( rt , out1 , TRUE );
	else
		CallRuntimeFunction_bool_SetBoolValue( rt , out1 , FALSE );
	return 0;
}

ZlangInvokeFunction ZlangInvokeFunction_string_Length;
int ZlangInvokeFunction_string_Length( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	struct ZlangDirectProperty_string	*obj_direct_prop = GetObjectDirectProperty(obj) ;
	struct ZlangObject			*out1 = GetOutputParameterInLocalObjectStack(rt,1) ;
	
	CallRuntimeFunction_int_SetIntValue( rt , out1 , obj_direct_prop->buf_len );
	
	return 0;
}

ZlangInvokeFunction ZlangInvokeFunction_string_BufferSize;
int ZlangInvokeFunction_string_BufferSize( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	struct ZlangDirectProperty_string	*obj_direct_prop = GetObjectDirectProperty(obj) ;
	struct ZlangObject			*out1 = GetOutputParameterInLocalObjectStack(rt,1) ;
	
	CallRuntimeFunction_int_SetIntValue( rt , out1 , obj_direct_prop->buf_size );
	
	return 0;
}

ZlangInvokeFunction ZlangInvokeFunction_string_AppendFormat_vargs;
int ZlangInvokeFunction_string_AppendFormat_vargs( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	int					in_params_count = GetInputParameterCountInLocalObjectStack( rt ) ;
	int					in_params_index ;
	struct ZlangObject			*in = NULL ;
	char					*format = NULL ;
	struct ZlangObject			*out = NULL ;
	int					formatting_count ;
	char					*p1 = NULL ;
	char					*p2 = NULL ;
	char					*p3 = NULL ;
	char					format_copy[32+1] ;
	int					format_copy_len = 0 ;
	char					*format_copy_end = NULL ;
	// char					*p_format_copy = NULL ;
	char					obj_name[ 256 + 1 ] ;
	struct ZlangDirectProperty_string	*obj_direct_prop = GetObjectDirectProperty(obj) ;
	int32_t					fill_len ;
	short					*s = NULL ;
	unsigned short				*us = NULL ;
	int					*i = NULL ;
	unsigned int				*ui = NULL ;
	long					*l = NULL ;
	unsigned long				*ul = NULL ;
	float					*f = NULL ;
	double					*d = NULL ;
	char					*str = NULL ;
	struct ZlangObject			*tostr = NULL ;
	char					*tostr_str = NULL ;
	int32_t					tostr_str_len ;
	
	int					nret = 0 ;
	
	in_params_index = 1 ;
	in = GetInputParameterInLocalObjectStack(rt,in_params_index) ;
	GetDataPtr( rt , in , (void**) & format , NULL );
	p1 = format ;
	
	out = GetOutputParameterInLocalObjectStack(rt,1) ;
	
	for( ; ; )
	{
		if( *(p1) == '\0' )
		{
			break;
		}
		else if( *(p1) == '%' )
		{
			p2 = p1 + 1 ;
			
			if( *(p2) == '%' )
			{
				format_copy[0] = '%' ;
				format_copy[1] = '%' ;
				format_copy[2] = '\0' ;
				format_copy_len = 1 ;
				fill_len = format_copy_len ;
				p3 = p2 ;
				goto _GOTO_FORMATTING;
			}
			else if( *(p2) == '{' )
			{
				/*
				%{o}
				%{o:.2lf}
				%{o:.2?}
				*/
				
				p1 = p2 + 1 ;
				for( p2 = p1 ; *(p2) ; p2++ )
				{
					if( *(p2) == ':' || *(p2) == '}' )
						break;
				}
				if( *(p2) == '\0' )
				{
					SET_RUNTIME_ERROR( rt , RUNTIME_ERROR , ZLANG_ERROR_FORMAT_STRING_NOT_COMPLETED , "format string[%.*s] not completed" , (int)(p2-p1),p1 )
					return GetRuntimeErrorNo(rt);
				}
				
				if( p2 - p1 == 0 || p2 - p1 > sizeof(obj_name)-1 )
				{
					SET_RUNTIME_ERROR( rt , RUNTIME_ERROR , ZLANG_ERROR_FORMAT_STRING_NOT_COMPLETED , "format string[%.*s] not completed" , (int)(p2-p1),p1 )
					return GetRuntimeErrorNo(rt);
				}
				
				memset( obj_name , 0x00 , sizeof(obj_name) );
				snprintf( obj_name , sizeof(obj_name)-1 , "%.*s" , (int)(p2-p1),p1 );
				in = QueryObjectByObjectNameInLowerLocalObjectsStack( rt , obj_name ) ;
				if( in == NULL )
				{
					SET_RUNTIME_ERROR( rt , RUNTIME_ERROR , ZLANG_ERROR_OBJECT_NOT_IMPORTED_OR_DECLARED , "object '%s' not imported or declared" , obj_name )
					return ZLANG_ERROR_OBJECT_NOT_IMPORTED_OR_DECLARED;
				}
				
				if( *(p2) == ':' )
				{
					p1 = p2 + 1 ;
					for( p2 = p1 ; *(p2) ; p2++ )
					{
						if( *(p2) == '}' )
							break;
					}
					if( *(p2) == '\0' )
					{
						SET_RUNTIME_ERROR( rt , RUNTIME_ERROR , ZLANG_ERROR_FORMAT_STRING_NOT_COMPLETED , "format string[%.*s] not completed" , (int)(p2-p1),p1 )
						return GetRuntimeErrorNo(rt);
					}
						
					format_copy_len = 1 + p2 - p1 ;
					if( format_copy_len+1 > sizeof(format_copy)-1 )
					{
						SET_RUNTIME_ERROR( rt , RUNTIME_ERROR , ZLANG_ERROR_FORMAT_STRING_TOO_LONG , "format string[%%%.*s] too long" , format_copy_len,p1 )
						return GetRuntimeErrorNo(rt);
					}
					format_copy[0] = '%' ;
					memcpy( format_copy+1 , p1 , format_copy_len-1 );
					format_copy[format_copy_len] = '\0' ;
					p3 = p2 ;
				}
				else
				{
					format_copy[0] = '%' ;
					format_copy[1] = '?' ;
					format_copy[2] = '\0' ;
					format_copy_len = 2 ;
					p3 = p2 ;
				}
			}
			else
			{
				/*
				%d
				%.2lf
				%?
				*/
				
				for( ; *(p2) ; p2++ )
				{
					if( *(p2) == 'd' || *(p2) == 'f' || *(p2) == 's' || *(p2) == 'b' || *(p2) == 'p' || *(p2) == '?' )
						break;
				}
				if( *(p2) == '\0' )
				{
					SET_RUNTIME_ERROR( rt , RUNTIME_ERROR , ZLANG_ERROR_FORMAT_STRING_NOT_COMPLETED , "format string[%.*s] not completed" , (int)(p2-p1),p1 )
					return GetRuntimeErrorNo(rt);
				}
				p3 = p2 ;
				
				format_copy_len = p2 - p1 + 1 ;
				if( format_copy_len+1 > sizeof(format_copy)-1 )
				{
					SET_RUNTIME_ERROR( rt , RUNTIME_ERROR , ZLANG_ERROR_FORMAT_STRING_TOO_LONG , "format string[%.*s] too long" , format_copy_len,p1 )
					return GetRuntimeErrorNo(rt);
				}
				memcpy( format_copy , p1 , format_copy_len );
				format_copy[format_copy_len] = '\0' ;
				
				in_params_index++;
				if( in_params_index > in_params_count )
				{
					SET_RUNTIME_ERROR( rt , RUNTIME_ERROR , ZLANG_ERROR_FORMAT_PLACEHOLDER_NOT_MATCHED_WITH_PARAMETER , "format place-holder not matched with parameter" )
					return GetRuntimeErrorNo(rt);
				}
				in = GetInputParameterInLocalObjectStack(rt,in_params_index) ;
			}
			
			format_copy_end = format_copy + format_copy_len-1 ;
			if( IsObjectPropertiesEntityNull(in) )
			{
				format_copy[0] = '%' ;
				format_copy[1] = 's' ;
				format_copy[2] = '\0' ;
				fill_len = snprintf( NULL , 0 , format_copy , ZLANG_null_STRING ) ;
			}
			else if( ( (format_copy_end[-1]=='h'&&format_copy_end[0]=='d') || format_copy_end[0]=='?' ) && IsTypeOf(rt,in,GetShortObjectInRuntimeObjectsHeap(rt)) )
			{
				if( format_copy_end[0] == '?' )
				{
					format_copy_end[0] = 'h' ;
					format_copy_end[1] = 'd' ;
					format_copy_end[2] = '\0' ;
					format_copy_len++;
				}
				GetDataPtr( rt , in , (void**) & s , NULL ) ;
				fill_len = snprintf( NULL , 0 , format_copy , (*s) ) ;
			}
			else if( ( (format_copy_end[-1]=='h'&&format_copy_end[0]=='u') || format_copy_end[0]=='?' ) && IsTypeOf(rt,in,GetUShortObjectInRuntimeObjectsHeap(rt)) )
			{
				if( format_copy_end[0] == '?' )
				{
					format_copy_end[0] = 'h' ;
					format_copy_end[1] = 'u' ;
					format_copy_end[2] = '\0' ;
					format_copy_len++;
				}
				GetDataPtr( rt , in , (void**) & us , NULL ) ;
				fill_len = snprintf( NULL , 0 , format_copy , (*s) ) ;
			}
			else if( ( (format_copy_end[-1]=='l'&&format_copy_end[0]=='d') || format_copy_end[0]=='?' ) && IsTypeOf(rt,in,GetLongObjectInRuntimeObjectsHeap(rt)) )
			{
				if( format_copy_end[0] == '?' )
				{
					format_copy_end[0] = 'l' ;
					format_copy_end[1] = 'd' ;
					format_copy_end[2] = '\0' ;
					format_copy_len++;
				}
				GetDataPtr( rt , in , (void**) & l , NULL ) ;
				fill_len = snprintf( NULL , 0 , format_copy , (*l) ) ;
			}
			else if( ( (format_copy_end[-1]=='l'&&format_copy_end[0]=='u') || format_copy_end[0]=='?' ) && IsTypeOf(rt,in,GetULongObjectInRuntimeObjectsHeap(rt)) )
			{
				if( format_copy_end[0] == '?' )
				{
					format_copy_end[0] = 'l' ;
					format_copy_end[1] = 'u' ;
					format_copy_end[2] = '\0' ;
					format_copy_len++;
				}
				GetDataPtr( rt , in , (void**) & ul , NULL ) ;
				fill_len = snprintf( NULL , 0 , format_copy , (*l) ) ;
			}
			else if( ( (format_copy_end[0]=='d') || format_copy_end[0]=='?' ) && IsTypeOf(rt,in,GetIntObjectInRuntimeObjectsHeap(rt)) )
			{
				if( format_copy_end[0] == '?' )
				{
					format_copy_end[0] = 'd' ;
				}
				GetDataPtr( rt , in , (void**) & i , NULL ) ;
				fill_len = snprintf( NULL , 0 , format_copy , (*i) ) ;
			}
			else if( ( (format_copy_end[0]=='u') || format_copy_end[0]=='?' ) && IsTypeOf(rt,in,GetUIntObjectInRuntimeObjectsHeap(rt)) )
			{
				if( format_copy_end[0] == '?' )
				{
					format_copy_end[0] = 'u' ;
				}
				GetDataPtr( rt , in , (void**) & ui , NULL ) ;
				fill_len = snprintf( NULL , 0 , format_copy , (*i) ) ;
			}
			else if( ( (format_copy_end[-1]=='l'&&format_copy_end[0]=='f') || format_copy_end[0]=='?' ) && IsTypeOf(rt,in,GetDoubleObjectInRuntimeObjectsHeap(rt)) )
			{
				if( format_copy_end[0] == '?' )
				{
					format_copy_end[0] = 'l' ;
					format_copy_end[1] = 'f' ;
					format_copy_end[2] = '\0' ;
					format_copy_len++;
				}
				GetDataPtr( rt , in , (void**) & d , NULL ) ;
				fill_len = snprintf( NULL , 0 , format_copy , (*d) ) ;
			}
			else if( ( (format_copy_end[0]=='f') || format_copy_end[0]=='?' ) && IsTypeOf(rt,in,GetFloatObjectInRuntimeObjectsHeap(rt)) )
			{
				if( format_copy_end[0] == '?' )
				{
					format_copy_end[0] = 'f' ;
				}
				GetDataPtr( rt , in , (void**) & f , NULL ) ;
				fill_len = snprintf( NULL , 0 , format_copy , (*f) ) ;
			}
			else if( ( (format_copy_end[0]=='s') || format_copy_end[0]=='?' ) && IsTypeOf(rt,in,GetStringObjectInRuntimeObjectsHeap(rt)) )
			{
				if( format_copy_end[0] == '?' )
				{
					format_copy_end[0] = 's' ;
				}
				GetDataPtr( rt , in , (void**) & str , NULL ) ;
				fill_len = snprintf( NULL , 0 , format_copy , str ) ;
			}
			else if( ( (format_copy_end[0]=='b') || format_copy_end[0]=='?' ) && IsTypeOf(rt,in,GetBoolObjectInRuntimeObjectsHeap(rt)) )
			{
				format_copy_end[0] = 's' ;
				
				nret = ToString( rt , in , & tostr ) ;
				if( nret )
					return nret;
				
				GetDataPtr( rt , tostr , (void**) & tostr_str , & tostr_str_len ) ;
				
				fill_len = snprintf( NULL , 0 , format_copy , tostr_str ) ;
			}
			else if( format_copy_end[0]=='p' )
			{
				fill_len = snprintf( NULL , 0 , format_copy , in ) ;
			}
			else
			{
				SET_RUNTIME_ERROR( rt , RUNTIME_ERROR , ZLANG_ERROR_FORMAT_STRING_NOT_MATCHED_WITH_PARAMETER , "format[%s] not matched with parameter[%s]" , format_copy , GetCloneObjectName(in) )
				return GetRuntimeErrorNo(rt);
			}

_GOTO_FORMATTING:
			nret = PrepareBuffer( rt , obj_direct_prop , fill_len ) ;
			if( nret )
				return nret;
			
			format_copy_end = format_copy + format_copy_len-1 ;
			if( format_copy_end[0]=='%' )
			{
				obj_direct_prop->buf_len += sprintf( obj_direct_prop->buf+obj_direct_prop->buf_len , format_copy ) ;
				TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "format\"%s\" -> formatting\"%.*s\" buf_size[%d] buf_len[%d]" , format_copy , fill_len,obj_direct_prop->buf+obj_direct_prop->buf_len-fill_len , obj_direct_prop->buf_size , obj_direct_prop->buf_len )
			}
			else if( IsObjectPropertiesEntityNull(in) )
			{
				obj_direct_prop->buf_len += sprintf( obj_direct_prop->buf+obj_direct_prop->buf_len , format_copy , ZLANG_null_STRING ) ;
				TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "format\"%s\" null -> formatting\"%.*s\" buf_size[%d] buf_len[%d]" , format_copy , fill_len,obj_direct_prop->buf+obj_direct_prop->buf_len-fill_len , obj_direct_prop->buf_size , obj_direct_prop->buf_len )
			}
			else if( (format_copy_end[-1]=='h'&&format_copy_end[0]=='d') && IsTypeOf(rt,in,GetShortObjectInRuntimeObjectsHeap(rt)) )
			{
				obj_direct_prop->buf_len += sprintf( obj_direct_prop->buf+obj_direct_prop->buf_len , format_copy , (*s) ) ;
				TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "format\"%s\" short\"%hd\" -> formatting\"%.*s\" buf_size[%d] buf_len[%d]" , format_copy , (*s) , fill_len,obj_direct_prop->buf+obj_direct_prop->buf_len-fill_len , obj_direct_prop->buf_size , obj_direct_prop->buf_len )
			}
			else if( (format_copy_end[-1]=='h'&&format_copy_end[0]=='u') && IsTypeOf(rt,in,GetUShortObjectInRuntimeObjectsHeap(rt)) )
			{
				obj_direct_prop->buf_len += sprintf( obj_direct_prop->buf+obj_direct_prop->buf_len , format_copy , (*s) ) ;
				TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "format\"%s\" ushort\"%hd\" -> formatting\"%.*s\" buf_size[%d] buf_len[%d]" , format_copy , (*us) , fill_len,obj_direct_prop->buf+obj_direct_prop->buf_len-fill_len , obj_direct_prop->buf_size , obj_direct_prop->buf_len )
			}
			else if( (format_copy_end[-1]=='l'&&format_copy_end[0]=='d') && IsTypeOf(rt,in,GetLongObjectInRuntimeObjectsHeap(rt)) )
			{
				obj_direct_prop->buf_len += sprintf( obj_direct_prop->buf+obj_direct_prop->buf_len , format_copy , (*l) ) ;
				TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "format\"%s\" long\"%ld\" -> formatting\"%.*s\" buf_size[%d] buf_len[%d]" , format_copy , (*l) , fill_len,obj_direct_prop->buf+obj_direct_prop->buf_len-fill_len , obj_direct_prop->buf_size , obj_direct_prop->buf_len )
			}
			else if( (format_copy_end[-1]=='l'&&format_copy_end[0]=='u') && IsTypeOf(rt,in,GetULongObjectInRuntimeObjectsHeap(rt)) )
			{
				obj_direct_prop->buf_len += sprintf( obj_direct_prop->buf+obj_direct_prop->buf_len , format_copy , (*l) ) ;
				TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "format\"%s\" ulong\"%ld\" -> formatting\"%.*s\" buf_size[%d] buf_len[%d]" , format_copy , (*ul) , fill_len,obj_direct_prop->buf+obj_direct_prop->buf_len-fill_len , obj_direct_prop->buf_size , obj_direct_prop->buf_len )
			}
			else if( format_copy_end[0]=='d' && IsTypeOf(rt,in,GetIntObjectInRuntimeObjectsHeap(rt)) )
			{
				obj_direct_prop->buf_len += sprintf( obj_direct_prop->buf+obj_direct_prop->buf_len , format_copy , (*i) ) ;
				TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "format\"%s\" int\"%d\" -> formatting\"%.*s\" buf_size[%d] buf_len[%d]" , format_copy , (*i) , fill_len,obj_direct_prop->buf+obj_direct_prop->buf_len-fill_len , obj_direct_prop->buf_size , obj_direct_prop->buf_len )
			}
			else if( format_copy_end[0]=='u' && IsTypeOf(rt,in,GetUIntObjectInRuntimeObjectsHeap(rt)) )
			{
				obj_direct_prop->buf_len += sprintf( obj_direct_prop->buf+obj_direct_prop->buf_len , format_copy , (*i) ) ;
				TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "format\"%s\" uint\"%d\" -> formatting\"%.*s\" buf_size[%d] buf_len[%d]" , format_copy , (*ui) , fill_len,obj_direct_prop->buf+obj_direct_prop->buf_len-fill_len , obj_direct_prop->buf_size , obj_direct_prop->buf_len )
			}
			else if( (format_copy_end[-1]=='l'&&format_copy_end[0]=='f') && IsTypeOf(rt,in,GetDoubleObjectInRuntimeObjectsHeap(rt)) )
			{
				obj_direct_prop->buf_len += sprintf( obj_direct_prop->buf+obj_direct_prop->buf_len , format_copy , (*d) ) ;
				TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "format\"%s\" double\"%lf\" -> formatting\"%.*s\" buf_size[%d] buf_len[%d]" , format_copy , (*d) , fill_len,obj_direct_prop->buf+obj_direct_prop->buf_len-fill_len , obj_direct_prop->buf_size , obj_direct_prop->buf_len )
			}
			else if( format_copy_end[0]=='f' && IsTypeOf(rt,in,GetFloatObjectInRuntimeObjectsHeap(rt)) )
			{
				obj_direct_prop->buf_len += sprintf( obj_direct_prop->buf+obj_direct_prop->buf_len , format_copy , (*f) ) ;
				TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "format\"%s\" float\"%f\" -> formatting\"%.*s\" buf_size[%d] buf_len[%d]" , format_copy , (*f) , fill_len,obj_direct_prop->buf+obj_direct_prop->buf_len-fill_len , obj_direct_prop->buf_size , obj_direct_prop->buf_len )
			}
			else if( format_copy_end[0]=='s' && IsTypeOf(rt,in,GetStringObjectInRuntimeObjectsHeap(rt)) )
			{
				obj_direct_prop->buf_len += sprintf( obj_direct_prop->buf+obj_direct_prop->buf_len , format_copy , str ) ;
				TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "format\"%s\" string\"%s\" -> formatting\"%.*s\" buf_size[%d] buf_len[%d]" , format_copy , str , fill_len,obj_direct_prop->buf+obj_direct_prop->buf_len-fill_len , obj_direct_prop->buf_size , obj_direct_prop->buf_len )
			}
			else if( format_copy_end[0]=='s' && IsTypeOf(rt,in,GetBoolObjectInRuntimeObjectsHeap(rt)) )
			{
				obj_direct_prop->buf_len += sprintf( obj_direct_prop->buf+obj_direct_prop->buf_len , format_copy , tostr_str ) ;
				TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "format\"%s\" bool\"%s\" -> formatting\"%.*s\" buf_size[%d] buf_len[%d]" , format_copy , tostr_str , fill_len,obj_direct_prop->buf+obj_direct_prop->buf_len-fill_len , obj_direct_prop->buf_size , obj_direct_prop->buf_len )
			}
			else if( format_copy_end[0]=='p' )
			{
				obj_direct_prop->buf_len += sprintf( obj_direct_prop->buf+obj_direct_prop->buf_len , format_copy , in ) ;
				TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "format\"%s\" void*\"%p\" -> formatting\"%.*s\" buf_size[%d] buf_len[%d]" , format_copy , in , fill_len,obj_direct_prop->buf+obj_direct_prop->buf_len-fill_len , obj_direct_prop->buf_size , obj_direct_prop->buf_len )
			}
			
			p1 = p3 + 1 ;
		}
		else
		{
			p3 = p1 + 1 ;
			
			for( ; *(p3) ; p3++ )
			{
				if( *(p3) == '%' )
				{
					--p3;
					break;
				}
			}
			if( *(p3) == '\0' )
				--p3;
			
			fill_len = p3 - p1 + 1 ;
			
			nret = PrepareBuffer( rt , obj_direct_prop , fill_len ) ;
			if( nret )
				return nret;
			
			memcpy( obj_direct_prop->buf+obj_direct_prop->buf_len , p1 , fill_len );
			obj_direct_prop->buf_len += fill_len ;
			obj_direct_prop->buf[obj_direct_prop->buf_len] = '\0' ;
			TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "formatting\"%.*s\" buf_size[%d] buf_len[%d]" , fill_len,obj_direct_prop->buf+obj_direct_prop->buf_len-fill_len , obj_direct_prop->buf_size , obj_direct_prop->buf_len )
			
			p1 = p3 + 1 ;
		}
	}
	
	if( in_params_index != in_params_count )
	{
		SET_RUNTIME_ERROR( rt , RUNTIME_ERROR , ZLANG_ERROR_FORMAT_PARAMETERS_NOT_MATCHED , "format parameters not matched , index[%d] count[%d]" , in_params_index , in_params_count )
		return GetRuntimeErrorNo(rt);
	}
	
	formatting_count = obj_direct_prop->buf_len ;
	FromDataPtr( rt , out , & formatting_count , sizeof(int) );
	
	return 0;
}

ZlangInvokeFunction ZlangInvokeFunction_string_Format_vargs;
int ZlangInvokeFunction_string_Format_vargs( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	struct ZlangDirectProperty_string	*obj_direct_prop = GetObjectDirectProperty(obj) ;
	
	obj_direct_prop->buf_len = 0 ;
	return ZlangInvokeFunction_string_AppendFormat_vargs( rt , obj );
}

ZlangInvokeFunction ZlangInvokeFunction_string_FormatString_string;
int ZlangInvokeFunction_string_FormatString_string( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	struct ZlangDirectProperty_string	*obj_direct_prop = GetObjectDirectProperty(obj) ;
	struct ZlangObject			*in = GetInputParameterInLocalObjectStack(rt,1) ;
	struct ZlangObject			*out = GetOutputParameterInLocalObjectStack(rt,1) ;
	char					*format = NULL ;
	int					fill_len ;
	char					*buf = NULL ;
	
	int					nret = 0 ;
	
	GetDataPtr( rt , in , (void**) & format , NULL );
	
	fill_len = snprintf( NULL , 0 , format , obj_direct_prop->buf ) ;
	buf = ZLMALLOC( fill_len+1 ) ;
	if( buf == NULL )
	{
		SET_RUNTIME_ERROR( rt , RUNTIME_ERROR , ZLANG_ERROR_ALLOC , "alloc memory for str buf" )
		return ZLANG_ERROR_ALLOC;
	}
	sprintf( buf , format , obj_direct_prop->buf );
	
	nret = FromCharPtr( rt , out , buf , fill_len ) ;
	TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "format\"%s\" string\"%s\" -> formatting\"%s\"" , format , obj_direct_prop->buf , buf )
	ZLFREE( buf );
	if( nret )
		return nret;
	
	return 0;
}

ZlangInvokeFunction ZlangInvokeFunction_string_IndexOf_string;
int ZlangInvokeFunction_string_IndexOf_string( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	struct ZlangDirectProperty_string	*obj_direct_prop = GetObjectDirectProperty(obj) ;
	struct ZlangObject			*in1 = GetInputParameterInLocalObjectStack(rt,1) ;
	struct ZlangObject			*out1 = GetOutputParameterInLocalObjectStack(rt,1) ;
	char					*str = NULL ;
	char					*p = NULL ;
	
	CallRuntimeFunction_string_GetStringValue( rt , in1 , & str , NULL );
	
	if( obj_direct_prop->buf == NULL )
	{
		CallRuntimeFunction_int_SetIntValue( rt , out1 , -1 );
		return 0;
	}
	
	obj_direct_prop->buf[obj_direct_prop->buf_len] = '\0' ;
	p = strstr( obj_direct_prop->buf , str ) ;
	if( p == NULL )
	{
		CallRuntimeFunction_int_SetIntValue( rt , out1 , -1 );
		return 0;
	}
	
	CallRuntimeFunction_int_SetIntValue( rt , out1 , p-obj_direct_prop->buf+1 );
	return 0;
}

ZlangInvokeFunction ZlangInvokeFunction_string_IsNumeric;
int ZlangInvokeFunction_string_IsNumeric( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	struct ZlangDirectProperty_string	*obj_direct_prop = GetObjectDirectProperty(obj) ;
	struct ZlangObject			*out1 = GetOutputParameterInLocalObjectStack(rt,1) ;
	char					*p = NULL ;
	
	if( obj_direct_prop->buf == NULL )
	{
		CallRuntimeFunction_bool_SetBoolValue( rt , out1 , TRUE );
		return 0;
	}
	
	for( p = obj_direct_prop->buf ; (*p) ; p++ )
	{
		if( '0' <= (*p) && (*p) <= '9' )
		{
		}
		else
		{
			CallRuntimeFunction_bool_SetBoolValue( rt , out1 , FALSE );
			return 0;
		}
	}
	
	CallRuntimeFunction_bool_SetBoolValue( rt , out1 , TRUE );
	return 0;
}

ZlangInvokeFunction ZlangInvokeFunction_string_IsAlphabetic;
int ZlangInvokeFunction_string_IsAlphabetic( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	struct ZlangDirectProperty_string	*obj_direct_prop = GetObjectDirectProperty(obj) ;
	struct ZlangObject			*out1 = GetOutputParameterInLocalObjectStack(rt,1) ;
	char					*p = NULL ;
	
	if( obj_direct_prop->buf == NULL )
	{
		CallRuntimeFunction_bool_SetBoolValue( rt , out1 , TRUE );
		return 0;
	}
	
	for( p = obj_direct_prop->buf ; (*p) ; p++ )
	{
		if( ( 'a' <= (*p) && (*p) <= 'z' ) || ( 'A' <= (*p) && (*p) <= 'Z' ) )
		{
		}
		else
		{
			CallRuntimeFunction_bool_SetBoolValue( rt , out1 , FALSE );
			return 0;
		}
	}
	
	CallRuntimeFunction_bool_SetBoolValue( rt , out1 , TRUE );
	return 0;
}

ZlangInvokeFunction ZlangInvokeFunction_string_IsNumericOrAlphabetic;
int ZlangInvokeFunction_string_IsNumericOrAlphabetic( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	struct ZlangDirectProperty_string	*obj_direct_prop = GetObjectDirectProperty(obj) ;
	struct ZlangObject			*out1 = GetOutputParameterInLocalObjectStack(rt,1) ;
	char					*p = NULL ;
	
	if( obj_direct_prop->buf == NULL )
	{
		CallRuntimeFunction_bool_SetBoolValue( rt , out1 , TRUE );
		return 0;
	}
	
	for( p = obj_direct_prop->buf ; (*p) ; p++ )
	{
		if( ( '0' <= (*p) && (*p) <= '9' ) || ( 'a' <= (*p) && (*p) <= 'z' ) || ( 'A' <= (*p) && (*p) <= 'Z' ) )
		{
		}
		else
		{
			CallRuntimeFunction_bool_SetBoolValue( rt , out1 , FALSE );
			return 0;
		}
	}
	
	CallRuntimeFunction_bool_SetBoolValue( rt , out1 , TRUE );
	return 0;
}

ZlangInvokeFunction ZlangInvokeFunction_string_Insert_int_string;
int ZlangInvokeFunction_string_Insert_int_string( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	struct ZlangDirectProperty_string	*obj_direct_prop = GetObjectDirectProperty(obj) ;
	struct ZlangObject			*in1 = GetInputParameterInLocalObjectStack(rt,1) ;
	struct ZlangObject			*in2 = GetInputParameterInLocalObjectStack(rt,2) ;
	int32_t					pos ;
	char					*buf2 = NULL ;
	int32_t					buf2_len ;
	int					nret = 0 ;
	
	CallRuntimeFunction_int_GetIntValue( rt , in1 , & pos );
	CallRuntimeFunction_string_GetStringValue( rt , in2 , & buf2 , & buf2_len );
	
	if( pos < 1 || pos > obj_direct_prop->buf_len+1 )
	{
		return 0;
	}
	
	if( obj_direct_prop->buf == NULL )
	{
		nret = FromCharPtr( rt , obj , buf2 , buf2_len ) ;
		if( nret )
		{
			TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "FromCharPtr failed[%d]" , nret )
			return nret;
		}
		
		return 0;
	}
	
	nret = PrepareBuffer( rt , obj_direct_prop , buf2_len ) ;
	if( nret )
	{
		TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "PrepareBuffer failed[%d] , fill_len[%"PRIi32"" , nret , buf2_len )
		return nret;
	}
	
	if( obj_direct_prop->buf_len-pos >= 0 )
	{
		memmove( obj_direct_prop->buf+(pos-1)+buf2_len , obj_direct_prop->buf+(pos-1) , obj_direct_prop->buf_len-pos );
	}
	memcpy( obj_direct_prop->buf+(pos-1) , buf2 , buf2_len );
	obj_direct_prop->buf_len += buf2_len ;
	obj_direct_prop->buf[obj_direct_prop->buf_len] = '\0' ;
	
	return 0;
}

static int ReplaceString( struct ZlangRuntime *rt , struct ZlangDirectProperty_string *obj_direct_prop , char *buf1 , int32_t buf1_len , char *buf2 , int32_t buf2_len , unsigned char is_replace_all )
{
	int32_t			diff_buf_len ;
	int32_t			len1 , len2 ;
	char			*offset_base = NULL ;
	int32_t			offset_base_len ;
	char			*p = NULL ;
	int			nret = 0 ;
	
	diff_buf_len = buf2_len - buf1_len ;
	
	offset_base = obj_direct_prop->buf ;
	offset_base_len = obj_direct_prop->buf_len ;
	for( ; ; )
	{
		p = strstr( offset_base , buf1 ) ;
		if( p == NULL )
			return 0;
		
		len1 = offset_base - obj_direct_prop->buf ;
		len2 = p - obj_direct_prop->buf ;
		nret = PrepareBuffer( rt , obj_direct_prop , diff_buf_len ) ;
		if( nret )
			return nret;
		offset_base = obj_direct_prop->buf + len1 ;
		p = obj_direct_prop->buf + len2 ;
		
		/*
		abcde
		 bc
		 xyz
		axyzde
		*/
		if( diff_buf_len )
		{
			memmove( p+buf2_len , p+buf1_len , offset_base_len-(p-offset_base+buf1_len) );
		}
		memcpy( p , buf2 , buf2_len );
		offset_base_len += diff_buf_len ;
		offset_base[offset_base_len] = '\0' ;
		
		obj_direct_prop->buf_len += diff_buf_len ;
		
		if( is_replace_all == 0 )
			break;
		
		offset_base_len -= p-offset_base + 1 ;
		offset_base = p + 1 ;
	}
	
	return 0;
}

ZlangInvokeFunction ZlangInvokeFunction_string_Replace_string_string;
int ZlangInvokeFunction_string_Replace_string_string( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	struct ZlangDirectProperty_string	*obj_direct_prop = GetObjectDirectProperty(obj) ;
	struct ZlangObject			*in1 = GetInputParameterInLocalObjectStack(rt,1) ;
	struct ZlangObject			*in2 = GetInputParameterInLocalObjectStack(rt,2) ;
	char					*buf1 = NULL ;
	int32_t					buf1_len ;
	char					*buf2 = NULL ;
	int32_t					buf2_len ;
	int					nret = 0 ;
	
	if( obj_direct_prop->buf == NULL )
		return 0;
	
	CallRuntimeFunction_string_GetStringValue( rt , in1 , & buf1 , & buf1_len );
	CallRuntimeFunction_string_GetStringValue( rt , in2 , & buf2 , & buf2_len );
	
	nret = ReplaceString( rt , obj_direct_prop , buf1 , buf1_len , buf2 , buf2_len , 0 ) ;
	if( nret )
	{
		TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "ReplaceString failed[%d]" , nret )
		return 0;
	}
	
	return 0;
}

ZlangInvokeFunction ZlangInvokeFunction_string_ReplaceAll_string_string;
int ZlangInvokeFunction_string_ReplaceAll_string_string( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	struct ZlangDirectProperty_string	*obj_direct_prop = GetObjectDirectProperty(obj) ;
	struct ZlangObject			*in1 = GetInputParameterInLocalObjectStack(rt,1) ;
	struct ZlangObject			*in2 = GetInputParameterInLocalObjectStack(rt,2) ;
	char					*buf1 = NULL ;
	int32_t					buf1_len ;
	char					*buf2 = NULL ;
	int32_t					buf2_len ;
	int					nret = 0 ;
	
	if( obj_direct_prop->buf == NULL )
		return 0;
	
	CallRuntimeFunction_string_GetStringValue( rt , in1 , & buf1 , & buf1_len );
	CallRuntimeFunction_string_GetStringValue( rt , in2 , & buf2 , & buf2_len );
	
	nret = ReplaceString( rt , obj_direct_prop , buf1 , buf1_len , buf2 , buf2_len , 1 ) ;
	if( nret )
	{
		TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "ReplaceString failed[%d]" , nret )
		return 0;
	}
	
	return 0;
}

ZlangInvokeFunction ZlangInvokeFunction_string_StartWith_string;
int ZlangInvokeFunction_string_StartWith_string( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	struct ZlangDirectProperty_string	*obj_direct_prop = GetObjectDirectProperty(obj) ;
	struct ZlangObject			*in1 = GetInputParameterInLocalObjectStack(rt,1) ;
	struct ZlangObject			*out1 = GetOutputParameterInLocalObjectStack(rt,1) ;
	char					*buf2 = NULL ;
	int32_t					buf2_len ;
	
	CallRuntimeFunction_string_GetStringValue( rt , in1 , & buf2 , & buf2_len );
	
	if( obj_direct_prop->buf == NULL )
	{
		CallRuntimeFunction_bool_SetBoolValue( rt , out1 , FALSE );
		return 0;
	}
	
	if( obj_direct_prop->buf_len < buf2_len )
	{
		CallRuntimeFunction_bool_SetBoolValue( rt , out1 , FALSE );
		return 0;
	}
	
	if( strncmp( obj_direct_prop->buf , buf2 , buf2_len ) == 0 )
		CallRuntimeFunction_bool_SetBoolValue( rt , out1 , TRUE );
	else
		CallRuntimeFunction_bool_SetBoolValue( rt , out1 , FALSE );
	return 0;
}

ZlangInvokeFunction ZlangInvokeFunction_string_StartCaseWith_string;
int ZlangInvokeFunction_string_StartCaseWith_string( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	struct ZlangDirectProperty_string	*obj_direct_prop = GetObjectDirectProperty(obj) ;
	struct ZlangObject			*in1 = GetInputParameterInLocalObjectStack(rt,1) ;
	struct ZlangObject			*out1 = GetOutputParameterInLocalObjectStack(rt,1) ;
	char					*buf2 = NULL ;
	int32_t					buf2_len ;
	
	CallRuntimeFunction_string_GetStringValue( rt , in1 , & buf2 , & buf2_len );
	
	if( obj_direct_prop->buf == NULL )
	{
		CallRuntimeFunction_bool_SetBoolValue( rt , out1 , FALSE );
		return 0;
	}
	
	if( obj_direct_prop->buf_len < buf2_len )
	{
		CallRuntimeFunction_bool_SetBoolValue( rt , out1 , FALSE );
		return 0;
	}
	
	if( strncasecmp( obj_direct_prop->buf , buf2 , buf2_len ) == 0 )
		CallRuntimeFunction_bool_SetBoolValue( rt , out1 , TRUE );
	else
		CallRuntimeFunction_bool_SetBoolValue( rt , out1 , FALSE );
	return 0;
}

ZlangInvokeFunction ZlangInvokeFunction_string_SubString_int_int;
int ZlangInvokeFunction_string_SubString_int_int( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	struct ZlangDirectProperty_string	*obj_direct_prop = GetObjectDirectProperty(obj) ;
	struct ZlangObject			*in1 = GetInputParameterInLocalObjectStack(rt,1) ;
	struct ZlangObject			*in2 = GetInputParameterInLocalObjectStack(rt,2) ;
	struct ZlangObject			*out1 = GetOutputParameterInLocalObjectStack(rt,1) ;
	int32_t					start_pos ;
	int32_t					end_pos ;
	int					nret = 0 ;
	
	CallRuntimeFunction_int_GetIntValue( rt , in1 , & start_pos );
	CallRuntimeFunction_int_GetIntValue( rt , in2 , & end_pos );
	
	if( start_pos < 1 || start_pos > obj_direct_prop->buf_len || end_pos < 1 || end_pos > obj_direct_prop->buf_len || end_pos < start_pos )
	{
		UnreferObject( rt , out1 );
	}
	else if( obj_direct_prop->buf )
	{
		/*
		obj_direct_prop->buf_len = end_pos-start_pos+1 ;
		memmove( obj_direct_prop->buf , obj_direct_prop->buf+(start_pos-1) , obj_direct_prop->buf_len );
		*/
		nret = FromCharPtr( rt , out1 , obj_direct_prop->buf+(start_pos-1) , end_pos-start_pos+1 ) ;
		if( nret )
		{
			TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "FromCharPtr failed[%d]" , nret )
			return nret;
		}
		
	}
	
	return 0;
}

ZlangInvokeFunction ZlangInvokeFunction_string_ToShort;
int ZlangInvokeFunction_string_ToShort( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	struct ZlangDirectProperty_string	*obj_direct_prop = GetObjectDirectProperty(obj) ;
	struct ZlangObject			*out1 = GetOutputParameterInLocalObjectStack(rt,1) ;
	char					*tmp = NULL ;
	int16_t					sht ;
	
	tmp = ZLSTRNDUP( obj_direct_prop->buf , obj_direct_prop->buf_len ) ;
	if( tmp == NULL )
	{
		SET_RUNTIME_ERROR( rt , RUNTIME_ERROR , ZLANG_ERROR_ALLOC , "alloc ZLSTRNDUP memory for ToInt" )
		return ZLANG_ERROR_ALLOC;
	}
	sht = (int16_t)atoi( tmp ) ;
	ZLFREE( tmp );
	
	CallRuntimeFunction_short_SetShortValue( rt , out1 , sht );
	return 0;
}

ZlangInvokeFunction ZlangInvokeFunction_string_ToInt;
int ZlangInvokeFunction_string_ToInt( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	struct ZlangDirectProperty_string	*obj_direct_prop = GetObjectDirectProperty(obj) ;
	struct ZlangObject			*out1 = GetOutputParameterInLocalObjectStack(rt,1) ;
	char					*tmp = NULL ;
	int32_t					i ;
	
	tmp = ZLSTRNDUP( obj_direct_prop->buf , obj_direct_prop->buf_len ) ;
	if( tmp == NULL )
	{
		SET_RUNTIME_ERROR( rt , RUNTIME_ERROR , ZLANG_ERROR_ALLOC , "alloc ZLSTRNDUP memory for ToInt" )
		return ZLANG_ERROR_ALLOC;
	}
	i = (int32_t)atoi( tmp ) ;
	ZLFREE( tmp );
	
	CallRuntimeFunction_int_SetIntValue( rt , out1 , i );
	return 0;
}

ZlangInvokeFunction ZlangInvokeFunction_string_ToLong;
int ZlangInvokeFunction_string_ToLong( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	struct ZlangDirectProperty_string	*obj_direct_prop = GetObjectDirectProperty(obj) ;
	struct ZlangObject			*out1 = GetOutputParameterInLocalObjectStack(rt,1) ;
	char					*tmp = NULL ;
	int64_t					l ;
	
	tmp = ZLSTRNDUP( obj_direct_prop->buf , obj_direct_prop->buf_len ) ;
	if( tmp == NULL )
	{
		SET_RUNTIME_ERROR( rt , RUNTIME_ERROR , ZLANG_ERROR_ALLOC , "alloc ZLSTRNDUP memory for ToLong" )
		return ZLANG_ERROR_ALLOC;
	}
	l = (int64_t)atol( tmp ) ;
	ZLFREE( tmp );
	
	CallRuntimeFunction_long_SetLongValue( rt , out1 , l );
	return 0;
}

ZlangInvokeFunction ZlangInvokeFunction_string_ToFloat;
int ZlangInvokeFunction_string_ToFloat( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	struct ZlangDirectProperty_string	*obj_direct_prop = GetObjectDirectProperty(obj) ;
	struct ZlangObject			*out1 = GetOutputParameterInLocalObjectStack(rt,1) ;
	char					*tmp = NULL ;
	float					f ;
	
	tmp = ZLSTRNDUP( obj_direct_prop->buf , obj_direct_prop->buf_len ) ;
	if( tmp == NULL )
	{
		SET_RUNTIME_ERROR( rt , RUNTIME_ERROR , ZLANG_ERROR_ALLOC , "alloc ZLSTRNDUP memory for ToFloat" )
		return ZLANG_ERROR_ALLOC;
	}
	f = (float)atof( tmp ) ;
	ZLFREE( tmp );
	
	CallRuntimeFunction_float_SetFloatValue( rt , out1 , f );
	return 0;
}

ZlangInvokeFunction ZlangInvokeFunction_string_ToDouble;
int ZlangInvokeFunction_string_ToDouble( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	struct ZlangDirectProperty_string	*obj_direct_prop = GetObjectDirectProperty(obj) ;
	struct ZlangObject			*out1 = GetOutputParameterInLocalObjectStack(rt,1) ;
	char					*tmp = NULL ;
	double					d ;
	
	tmp = ZLSTRNDUP( obj_direct_prop->buf , obj_direct_prop->buf_len ) ;
	if( tmp == NULL )
	{
		SET_RUNTIME_ERROR( rt , RUNTIME_ERROR , ZLANG_ERROR_ALLOC , "alloc ZLSTRNDUP memory for ToDouble" )
		return ZLANG_ERROR_ALLOC;
	}
	d = (double)atof( tmp ) ;
	ZLFREE( tmp );
	
	CallRuntimeFunction_double_SetDoubleValue( rt , out1 , d );
	return 0;
}

ZlangInvokeFunction ZlangInvokeFunction_string_LowerCase;
int ZlangInvokeFunction_string_LowerCase( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	struct ZlangDirectProperty_string	*obj_direct_prop = GetObjectDirectProperty(obj) ;
	char					*p = NULL ;
	int32_t					l ;
	
	for( l = 0 , p = obj_direct_prop->buf  ; l < obj_direct_prop->buf_len ; l++ , p++ )
	{
		if( 'A' <= (*p) && (*p) <= 'Z' )
			(*p) = tolower(*p) ;
	}
	
	return 0;
}

ZlangInvokeFunction ZlangInvokeFunction_string_UpperCase;
int ZlangInvokeFunction_string_UpperCase( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	struct ZlangDirectProperty_string	*obj_direct_prop = GetObjectDirectProperty(obj) ;
	char					*p = NULL ;
	int32_t					l ;
	
	for( l = 0 , p = obj_direct_prop->buf  ; l < obj_direct_prop->buf_len ; l++ , p++ )
	{
		if( 'a' <= (*p) && (*p) <= 'z' )
			(*p) = toupper(*p) ;
	}
	
	return 0;
}

ZlangInvokeFunction ZlangInvokeFunction_string_Trim;
int ZlangInvokeFunction_string_Trim( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	struct ZlangDirectProperty_string	*obj_direct_prop = GetObjectDirectProperty(obj) ;
	int32_t					l ;
	
	for( l = obj_direct_prop->buf_len-1 ; l >= 0 ; l-- )
	{
		if( obj_direct_prop->buf[l] == ' ' || obj_direct_prop->buf[l] == '\b' || obj_direct_prop->buf[l] == '\t' || obj_direct_prop->buf[l] == '\r' || obj_direct_prop->buf[l] == '\n' || obj_direct_prop->buf[l] == '\f' )
		{
			obj_direct_prop->buf[l] = '\0' ;
			obj_direct_prop->buf_len--;
		}
		else
		{
			break;
		}
	}
	if( l < 0 )
		return 0;
	
	for( l = 0 ; l < obj_direct_prop->buf_len ; l++ )
	{
		if( obj_direct_prop->buf[l] == ' ' || obj_direct_prop->buf[l] == '\b' || obj_direct_prop->buf[l] == '\t' || obj_direct_prop->buf[l] == '\r' || obj_direct_prop->buf[l] == '\n' || obj_direct_prop->buf[l] == '\f' )
		{
			;
		}
		else
		{
			break;
		}
	}
	if( l > 0 )
	{
		obj_direct_prop->buf_len -= l ;
		memmove( obj_direct_prop->buf , obj_direct_prop->buf+l , obj_direct_prop->buf_len );
		obj_direct_prop->buf[obj_direct_prop->buf_len] = '\0' ;
	}
	
	return 0;
}

#include "pcre.h"

#define OVECCOUNT	100*3

ZlangInvokeFunction ZlangInvokeFunction_RegexpMatch_string;
int ZlangInvokeFunction_RegexpMatch_string( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	struct ZlangDirectProperty_string	*obj_direct_prop = GetObjectDirectProperty(obj) ;
	struct ZlangObject			*in1 = GetInputParameterInLocalObjectStack(rt,1) ;
	struct ZlangObject			*out1 = GetOutputParameterInLocalObjectStack(rt,1) ;
	char					*pattern = NULL ;
	int32_t					pattern_len ;
	pcre					*pattern_re = NULL ;
	const char				*errptr = NULL ;
	int					erroffset ;
	int					ovector[ OVECCOUNT ] = { 0 } ;
	int					match_count ;
	
	CallRuntimeFunction_string_GetStringValue( rt , in1 , & pattern , & pattern_len );
	
	pattern_re = pcre_compile( pattern , 0 , & errptr , & erroffset , NULL ) ;
	if( pattern_re == NULL )
	{
		TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "pcre_compile[%s] failed" , pattern )
		CallRuntimeFunction_int_SetIntValue( rt , out1 , -1 );
		return 0;
	}
	else
	{
		TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "pcre_compile[%s] ok" , pattern )
	}
	
	match_count = pcre_exec( pattern_re , NULL , obj_direct_prop->buf , obj_direct_prop->buf_len , 0 , 0 , ovector , OVECCOUNT ) ;
	if( match_count == 0 || match_count == PCRE_ERROR_NOMATCH )
	{
		TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "pcre_exec[%.*s] not matched" , obj_direct_prop->buf_len,obj_direct_prop->buf )
		free( pattern_re );
		CallRuntimeFunction_int_SetIntValue( rt , out1 , 0 );
		return 0;
	}
	else if( match_count < 0 )
	{
		TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "pcre_exec[%.*s] failed[%d]" , obj_direct_prop->buf_len,obj_direct_prop->buf , match_count )
		free( pattern_re );
		CallRuntimeFunction_int_SetIntValue( rt , out1 , -2 );
		return 0;
	}
	else
	{
		TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "pcre_exec[%.*s] matched" , obj_direct_prop->buf_len,obj_direct_prop->buf )
		free( pattern_re );
		CallRuntimeFunction_int_SetIntValue( rt , out1 , match_count );
		return 0;
	}
}

ZlangFromCharPtrFunction ZlangFromCharPtr_string;

ZlangInvokeFunction ZlangInvokeFunction_RegexpExtract_vargs;
int ZlangInvokeFunction_RegexpExtract_vargs( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	struct ZlangDirectProperty_string	*obj_direct_prop = GetObjectDirectProperty(obj) ;
	struct ZlangObject			*in1 = NULL ;
	struct ZlangObject			*inN = NULL ;
	int					in_count ;
	int					in_no ;
	struct ZlangObject			*out1 = GetOutputParameterInLocalObjectStack(rt,1) ;
	char					*pattern = NULL ;
	int32_t					pattern_len ;
	pcre					*pattern_re = NULL ;
	const char				*errptr = NULL ;
	int					erroffset ;
	int					ovector[ OVECCOUNT ] = { 0 } ;
	int					match_count = 0 ;
	int					match_no ;
	int					nret = 0 ;
	
	in_count = GetInputParameterCountInLocalObjectStack( rt ) ;
	if( in_count <= 1 )
	{
		TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "in param count[%d] invalid" , in_count )
		CallRuntimeFunction_int_SetIntValue( rt , out1 , -11 );
		return 0;
	}
	
	in1 = GetInputParameterInLocalObjectStack(rt,1) ;
	CallRuntimeFunction_string_GetStringValue( rt , in1 , & pattern , & pattern_len );
	
	pattern_re = pcre_compile( pattern , 0 , & errptr , & erroffset , NULL ) ;
	if( pattern_re == NULL )
	{
		TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "pcre_compile[%s] failed" , pattern )
		CallRuntimeFunction_int_SetIntValue( rt , out1 , -1 );
		return 0;
	}
	else
	{
		TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "pcre_compile[%s] ok" , pattern )
	}
	
	match_count = pcre_exec( pattern_re , NULL , obj_direct_prop->buf , obj_direct_prop->buf_len , 0 , 0 , ovector , OVECCOUNT ) ;
	if( match_count == 0 || match_count == PCRE_ERROR_NOMATCH )
	{
		TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "pcre_exec[%.*s] not matched" , obj_direct_prop->buf_len,obj_direct_prop->buf )
		free( pattern_re );
		CallRuntimeFunction_int_SetIntValue( rt , out1 , 0 );
		return 0;
	}
	else if( match_count < 0 )
	{
		TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "pcre_exec[%.*s] failed[%d]" , obj_direct_prop->buf_len,obj_direct_prop->buf , match_count )
		free( pattern_re );
		CallRuntimeFunction_int_SetIntValue( rt , out1 , -2 );
		return 0;
	}
	else
	{
		TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "pcre_exec[%.*s] matched" , obj_direct_prop->buf_len,obj_direct_prop->buf )
	}
	
	for( match_no = 1 , in_no = 2 ; match_no <= match_count ; match_no++ , in_no++ )
	{
		if( match_no >= in_count )
			break;
		
		inN = GetInputParameterInLocalObjectStack(rt,in_no) ;
		
		TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "ovector[%d][%d][%.*s]" , ovector[match_no*2] , ovector[match_no*2+1] , ovector[match_no*2+1]-ovector[match_no*2],obj_direct_prop->buf+ovector[match_no*2] )
		if( ovector[match_no*2+1] <= 0 )
			continue;
		
		nret = ZlangFromCharPtr_string( rt , inN , obj_direct_prop->buf+ovector[match_no*2] , ovector[match_no*2+1]-ovector[match_no*2] ) ;
		if( nret )
		{
			TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "ZlangFromCharPtr_string return[%d]" , nret )
			free( pattern_re );
			CallRuntimeFunction_int_SetIntValue( rt , out1 , -4 );
			return 0;
		}
	}
	
	free( pattern_re );
	CallRuntimeFunction_int_SetIntValue( rt , out1 , match_count );
	return 0;
}

static int RegexpReplace_string( struct ZlangRuntime *rt , struct ZlangObject *obj , unsigned char is_replace_all )
{
	struct ZlangDirectProperty_string	*obj_direct_prop = GetObjectDirectProperty(obj) ;
	struct ZlangObject			*in1 = GetInputParameterInLocalObjectStack(rt,1) ;
	struct ZlangObject			*in2 = GetInputParameterInLocalObjectStack(rt,2) ;
	struct ZlangObject			*out1 = GetOutputParameterInLocalObjectStack(rt,1) ;
	char					*pattern = NULL ;
	int32_t					pattern_len ;
	char					*replace_to = NULL ;
	int32_t					replace_to_len ;
	pcre					*pattern_re = NULL ;
	const char				*errptr = NULL ;
	int					erroffset ;
	int					ovector[ OVECCOUNT ] = { 0 } ;
	int					ovector_len ;
	int					match_count ;
	int					find_offset ;
	int					dd_len = 0 ;
	int					nret = 0 ;
	
	CallRuntimeFunction_string_GetStringValue( rt , in1 , & pattern , & pattern_len );
	CallRuntimeFunction_string_GetStringValue( rt , in2 , & replace_to , & replace_to_len );
	
	pattern_re = pcre_compile( pattern , 0 , & errptr , & erroffset , NULL ) ;
	if( pattern_re == NULL )
	{
		TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "pcre_compile[%s] failed" , pattern )
		CallRuntimeFunction_int_SetIntValue( rt , out1 , -1 );
		return 0;
	}
	else
	{
		TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "pcre_compile[%s] ok" , pattern )
	}
	
	find_offset = 0 ;
_GOTO_EXEC_AGAIN :
	match_count = pcre_exec( pattern_re , NULL , obj_direct_prop->buf+find_offset , obj_direct_prop->buf_len-find_offset , 0 , 0 , ovector , OVECCOUNT ) ;
	if( match_count == 0 || match_count == PCRE_ERROR_NOMATCH )
	{
		TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "pcre_exec[%.*s] not matched" , obj_direct_prop->buf_len,obj_direct_prop->buf )
		free( pattern_re );
		CallRuntimeFunction_int_SetIntValue( rt , out1 , find_offset?2:0 );
		return 0;
	}
	else if( match_count < 0 )
	{
		TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "pcre_exec[%.*s] failed[%d]" , obj_direct_prop->buf_len,obj_direct_prop->buf , match_count )
		free( pattern_re );
		CallRuntimeFunction_int_SetIntValue( rt , out1 , -2 );
		return 0;
	}
	else
	{
		TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "pcre_exec[%.*s] matched" , obj_direct_prop->buf_len,obj_direct_prop->buf )
	}
	
	TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "find_offset[%d] ovector[%d][%d][%.*s]" , find_offset , ovector[2] , ovector[2+1] , ovector[2+1]-ovector[2],obj_direct_prop->buf+ovector[2] )
	if( ovector[2+1] <= 0 )
	{
		free( pattern_re );
		CallRuntimeFunction_int_SetIntValue( rt , out1 , 0 );
		return 0;
	}
	
	ovector_len = ovector[2+1] - ovector[2] ;
	if( ovector_len != replace_to_len )
	{
		dd_len = replace_to_len - ovector_len ;
		if( dd_len > 0 )
		{
			nret = PrepareBuffer( rt , obj_direct_prop , dd_len ) ;
			if( nret )
			{
				TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "PrepareBuffer failed[%d]" , nret )
				free( pattern_re );
				return nret;
			}
		}
		
		memmove( obj_direct_prop->buf+find_offset+ovector[2+1]+dd_len , obj_direct_prop->buf+find_offset+ovector[2+1] , obj_direct_prop->buf_len-find_offset-ovector[2+1] );
	}
	
	memcpy( obj_direct_prop->buf+find_offset+ovector[2] , replace_to , replace_to_len );
	
	if( ovector_len != replace_to_len )
	{
		obj_direct_prop->buf_len += dd_len ;
		obj_direct_prop->buf[obj_direct_prop->buf_len] = '\0' ;
	}
	
	if( is_replace_all )
	{
		find_offset += ovector[2+1] ;
		goto _GOTO_EXEC_AGAIN;
	}
	else
	{
		free( pattern_re );
		CallRuntimeFunction_int_SetIntValue( rt , out1 , match_count );
		return 0;
	}
}

ZlangInvokeFunction ZlangInvokeFunction_RegexpReplace_string_string;
int ZlangInvokeFunction_RegexpReplace_string_string( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	return RegexpReplace_string( rt , obj , 0 );
}

ZlangInvokeFunction ZlangInvokeFunction_RegexpReplaceAll_string_string;
int ZlangInvokeFunction_RegexpReplaceAll_string_string( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	return RegexpReplace_string( rt , obj , 1 );
}

#define REWRITE_PATTERN		"(\\([0-9]+\\))"

ZlangInvokeFunction ZlangInvokeFunction_RegexpRewrite_string_string;
int ZlangInvokeFunction_RegexpRewrite_string_string( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	struct ZlangDirectProperty_string	*obj_direct_prop = GetObjectDirectProperty(obj) ;
	struct ZlangObject			*in1 = GetInputParameterInLocalObjectStack(rt,1) ;
	struct ZlangObject			*in2 = GetInputParameterInLocalObjectStack(rt,2) ;
	struct ZlangObject			*out1 = GetOutputParameterInLocalObjectStack(rt,1) ;
	char					*pattern = NULL ;
	int32_t					pattern_len ;
	pcre					*pattern_re = NULL ;
	pcre					*rewrite_re = NULL ;
	const char				*errptr = NULL ;
	int					erroffset ;
	struct ZlangObject			*rewrite_obj = NULL ;
	struct ZlangDirectProperty_string	*rewrite_obj_direct_prop = NULL ;
	int					pattern_ovector[ OVECCOUNT ] = { 0 } ;
	int					pattern_ovector_len ;
	int					pattern_match_count ;
	int					rewrite_ovector[ OVECCOUNT ] = { 0 } ;
	int					rewrite_ovector_len ;
	int					rewrite_match_count ;
	int					index ;
	char					*p_index = NULL ;
	char					*p_index_end = NULL ;
	int					dd_len = 0 ;
	int					rewrite_find_offset ;
	int					nret = 0 ;
	
	CallRuntimeFunction_string_GetStringValue( rt , in1 , & pattern , & pattern_len );
	
	pattern_re = pcre_compile( pattern , 0 , & errptr , & erroffset , NULL ) ;
	if( pattern_re == NULL )
	{
		TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "pattern pcre_compile[%s] failed" , pattern )
		CallRuntimeFunction_int_SetIntValue( rt , out1 , -1 );
		return 0;
	}
	else
	{
		TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "pattern pcre_compile[%s] ok" , pattern )
	}
	
	rewrite_re = pcre_compile( REWRITE_PATTERN , 0 , & errptr , & erroffset , NULL ) ;
	if( rewrite_re == NULL )
	{
		TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "rewrite pcre_compile[%s] failed" , REWRITE_PATTERN )
		free( pattern_re );
		CallRuntimeFunction_int_SetIntValue( rt , out1 , -1 );
		return 0;
	}
	else
	{
		TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "rewrite pcre_compile[%s] ok" , REWRITE_PATTERN )
	}
	
	nret = CloneObject( rt , & rewrite_obj , NULL , in2 ) ;
	if( nret )
	{
		TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "CloneObject failed[%d]" , nret )
		free( pattern_re );
		free( rewrite_re );
		CallRuntimeFunction_int_SetIntValue( rt , out1 , -1 );
		return nret;
	}
	
	rewrite_obj_direct_prop = GetObjectDirectProperty( rewrite_obj ) ;
	
	pattern_match_count = pcre_exec( pattern_re , NULL , obj_direct_prop->buf , obj_direct_prop->buf_len , 0 , 0 , pattern_ovector , OVECCOUNT ) ;
	if( pattern_match_count == 0 || pattern_match_count == PCRE_ERROR_NOMATCH )
	{
		TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "pattern pcre_exec[%.*s] not matched" , obj_direct_prop->buf_len,obj_direct_prop->buf )
		free( pattern_re );
		free( rewrite_re );
		DestroyObject( rt , rewrite_obj );
		CallRuntimeFunction_int_SetIntValue( rt , out1 , 0 );
		return 0;
	}
	else if( pattern_match_count < 0 )
	{
		TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "pattern pcre_exec[%.*s] failed[%d]" , obj_direct_prop->buf_len,obj_direct_prop->buf , pattern_match_count )
		free( pattern_re );
		free( rewrite_re );
		DestroyObject( rt , rewrite_obj );
		CallRuntimeFunction_int_SetIntValue( rt , out1 , -2 );
		return 0;
	}
	else
	{
		TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "pattern pcre_exec[%.*s] matched" , obj_direct_prop->buf_len,obj_direct_prop->buf )
	}
	
	rewrite_find_offset = 0 ;
	for( ; ; )
	{
		rewrite_match_count = pcre_exec( rewrite_re , NULL , rewrite_obj_direct_prop->buf+rewrite_find_offset , rewrite_obj_direct_prop->buf_len-rewrite_find_offset , 0 , 0 , rewrite_ovector , OVECCOUNT ) ;
		if( rewrite_match_count == 0 || rewrite_match_count == PCRE_ERROR_NOMATCH )
		{
			TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "rewrite pcre_exec[%.*s] not matched" , rewrite_obj_direct_prop->buf_len-rewrite_find_offset,rewrite_obj_direct_prop->buf+rewrite_find_offset )
			if( rewrite_find_offset > 0 )
			{
				nret = ZlangFromCharPtr_string( rt , obj , rewrite_obj_direct_prop->buf , rewrite_obj_direct_prop->buf_len ) ;
				if( nret )
				{
					TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "ZlangFromCharPtr_string failed[%d]" , nret )
					free( pattern_re );
					free( rewrite_re );
					DestroyObject( rt , rewrite_obj );
					return nret;
				}
			}
			free( pattern_re );
			free( rewrite_re );
			DestroyObject( rt , rewrite_obj );
			CallRuntimeFunction_int_SetIntValue( rt , out1 , rewrite_find_offset?2:0 );
			return 0;
		}
		else if( rewrite_match_count < 0 )
		{
			TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "rewrite pcre_exec[%.*s] failed[%d]" , rewrite_obj_direct_prop->buf_len-rewrite_find_offset,rewrite_obj_direct_prop->buf+rewrite_find_offset , rewrite_match_count )
			free( pattern_re );
			free( rewrite_re );
			DestroyObject( rt , rewrite_obj );
			return 0;
		}
		else
		{
			TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "rewrite pcre_exec[%.*s] matched" , rewrite_obj_direct_prop->buf_len-rewrite_find_offset,rewrite_obj_direct_prop->buf+rewrite_find_offset )
		}
		
		TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "rewrite_find_offset[%d] rewrite_ovector[%d][%d][%.*s]" , rewrite_find_offset , rewrite_ovector[2] , rewrite_ovector[2+1] , rewrite_ovector[2+1]-rewrite_ovector[2],rewrite_obj_direct_prop->buf+rewrite_ovector[2] )
		
		index = 0 ;
		for( p_index = rewrite_obj_direct_prop->buf+rewrite_find_offset+rewrite_ovector[2]+1 , p_index_end = rewrite_obj_direct_prop->buf+rewrite_find_offset+rewrite_ovector[2+1]-1 ; p_index < p_index_end ; p_index++ )
		{
			index = index * 10 + (*p_index)-'0' ;
		}
		if( index > pattern_match_count - 1 )
		{
			TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "index[%d] > pattern_ovector_count-1[%d]" , index , pattern_match_count-1 )
			free( pattern_re );
			free( rewrite_re );
			DestroyObject( rt , rewrite_obj );
			CallRuntimeFunction_int_SetIntValue( rt , out1 , -3 );
			return 0;
		}
		
		pattern_ovector_len = pattern_ovector[index*2+1] - pattern_ovector[index*2] ;
		rewrite_ovector_len = rewrite_ovector[2+1] - rewrite_ovector[2] ;
		dd_len = rewrite_ovector_len - pattern_ovector_len ;
		if( dd_len > 0 )
		{
			nret = PrepareBuffer( rt , rewrite_obj_direct_prop , dd_len ) ;
			if( nret )
			{
				TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "PrepareBuffer failed[%d]" , nret )
				free( pattern_re );
				free( rewrite_re );
				DestroyObject( rt , rewrite_obj );
				return nret;
			}
		}
		
		memmove( rewrite_obj_direct_prop->buf+rewrite_find_offset+rewrite_ovector[2+1]+dd_len , rewrite_obj_direct_prop->buf+rewrite_find_offset+rewrite_ovector[2+1] , rewrite_obj_direct_prop->buf_len-rewrite_find_offset-rewrite_ovector[2+1] );
		memcpy( rewrite_obj_direct_prop->buf+rewrite_find_offset+rewrite_ovector[2] , obj_direct_prop->buf+pattern_ovector[index*2] , pattern_ovector_len );
		
		if( dd_len )
		{
			rewrite_obj_direct_prop->buf_len += dd_len ;
			rewrite_obj_direct_prop->buf[obj_direct_prop->buf_len] = '\0' ;
		}
		
		rewrite_find_offset += rewrite_ovector[2+1] ;
	}
}

static int string_Split_string_string( struct ZlangRuntime *rt , struct ZlangObject *obj , struct ZlangObject *sepstr_obj , struct ZlangObject *ignstr_obj , struct ZlangObject *array_obj )
{
	struct ZlangDirectProperty_string	*obj_direct_prop = GetObjectDirectProperty(obj) ;
	char					*sepstr = NULL ;
	int32_t					sepstr_len ;
	char					*ignstr = NULL ;
	int32_t					ignstr_len ;
	
	char					*objstr_begin = NULL ;
	char					*objstr_end = NULL ;
	char					*sepstr_begin = NULL ;
	char					*sepstr_end = NULL ;
	char					*p_objstr_matched_begin = NULL ;
	int					p_objstr_matched_begin_len = 0 ;
	char					*p_objstr_matching = NULL ;
	char					*p_sepstr_matching = NULL ;
	int					objstr_step_len ;
	int					sepstr_step_len ;
	char					*p_objstr_unmatched_begin = NULL ;
	
	int					nret = 0 ;
	
	CallRuntimeFunction_string_GetStringValue( rt , sepstr_obj , & sepstr , & sepstr_len );
	if( sepstr_len == 0 )
	{
		TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "sepstr length[%"PRIi32"] invalid" , sepstr_len )
		return 1;
	}
	
	if( ignstr_obj )
	{
		CallRuntimeFunction_string_GetStringValue( rt , ignstr_obj , & ignstr , & ignstr_len );
		if( sepstr_len == 0 )
		{
			TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "ignstr length[%"PRIi32"] invalid" , ignstr_len )
			return 2;
		}
	}
	else
	{
		ignstr_len = 0 ;
	}
	
	objstr_begin = obj_direct_prop->buf ;
	objstr_end = objstr_begin + obj_direct_prop->buf_len-1 ;
	TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "objstr[%.*s]" , (int)(objstr_end-objstr_begin+1),objstr_begin )
	p_objstr_matching = objstr_begin ;
	p_objstr_unmatched_begin = objstr_begin ;
	
	sepstr_begin = sepstr ;
	sepstr_end = sepstr + sepstr_len-1 ;
	TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "sepstr[%.*s]" , (int)(sepstr_end-sepstr_begin+1),sepstr_begin )
	p_sepstr_matching = sepstr_begin ;
	
	for( ; ; )
	{
		/*
		"hello world"
		     " "
		
		"hello world"
		   "ld"
		         "ld"
		*/
		
		if( (*p_objstr_matching) == '\0' )
		{
			p_objstr_matched_begin = p_objstr_matching ;
			p_objstr_matched_begin_len = 0 ;
			goto _GOTO_APPEND_ARRAY_ELEMENT;
		}
		
		objstr_step_len = EvaluateOneWbyteLength( GetRuntimeCharset(rt) , (unsigned char *)p_objstr_matching , (unsigned char *)objstr_end ) ;
		if( objstr_step_len <= 0 )
		{
			TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "objstr_matching[%.*s] evaluate invalid" , (int)(objstr_end-p_objstr_matching+1),p_objstr_matching )
			return 3;
		}
		
		sepstr_step_len = EvaluateOneWbyteLength( GetRuntimeCharset(rt) , (unsigned char *)p_sepstr_matching , (unsigned char *)sepstr_end ) ;
		if( sepstr_step_len <= 0 )
		{
			TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "sepstr_matching[%.*s] evaluate invalid" , (int)(sepstr_end-p_sepstr_matching+1),p_sepstr_matching )
			return 4;
		}
		
		TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "objstr_matching[%.*s] evaluate ok | sepstr_matching[%.*s] evaluate ok" , objstr_step_len,p_objstr_matching , sepstr_step_len,p_sepstr_matching )
		
		if
		(
			objstr_step_len == sepstr_step_len
			&&
			(
				( objstr_step_len == 1 && (*p_objstr_matching) == (*p_sepstr_matching) )
				||
				( objstr_step_len > 1 && MEMCMP( p_objstr_matching , == , p_sepstr_matching , objstr_step_len ) )
			)
		)
		{
			if( p_objstr_matched_begin == NULL )
			{
				TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "  wbyte matched first" )
				p_objstr_matched_begin = p_objstr_matching ;
				p_objstr_matched_begin_len = objstr_step_len ;
			}
			else
			{
				TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "  wbyte matched" )
			}
			
			p_objstr_matching += objstr_step_len ;
			p_sepstr_matching += sepstr_step_len ;
			
			if( p_sepstr_matching > sepstr_end )
			{
_GOTO_APPEND_ARRAY_ELEMENT :
				{
					char		*cutstr = p_objstr_unmatched_begin ;
					int32_t		cutstr_len = p_objstr_matched_begin-p_objstr_unmatched_begin ;
					
					if(
						ignstr == NULL
						||
						STRNNCMP( cutstr , cutstr_len , != , ignstr , ignstr_len )
					)
					{
						struct ZlangObject	*str_obj = NULL ;
						
						str_obj = CloneStringObject( rt , NULL ) ;
						if( str_obj == NULL )
						{
							TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "  CloneStringObject failed" )
							return 5;
						}
						
						nret = CallRuntimeFunction_string_SetStringValue( rt , str_obj , cutstr , cutstr_len ) ;
						if( nret )
						{
							TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "  CallRuntimeFunction_string_SetStringValue failed[%d]" , nret )
							return 6;
						}
						
						nret = CallRuntimeFunction_array_Append( rt , array_obj , str_obj , NULL ) ;
						if( nret )
						{
							TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "  CallRuntimeFunction_array_Append failed[%d]" , nret )
							return 7;
						}
						else
						{
							TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "  CallRuntimeFunction_array_Append ok , str[%.*s]" , (int)(cutstr_len),cutstr )
						}
						
						DestroyObject( rt , str_obj );
					}
					
					if( (*p_objstr_matching) == '\0' && p_objstr_matched_begin_len == 0 )
						break;
					
					p_objstr_unmatched_begin = p_objstr_matching ;
					p_sepstr_matching = sepstr_begin ;
					p_objstr_matched_begin = NULL ;
					p_objstr_matched_begin_len = 0 ;
				}
			}
		}
		else
		{
			if( p_objstr_matched_begin )
			{
				TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "  wbyte interupt matching" )
				p_objstr_matching = p_objstr_matched_begin + p_objstr_matched_begin_len ;
				p_sepstr_matching = sepstr_begin ;
				p_objstr_unmatched_begin = p_objstr_matching ;
				p_objstr_matched_begin = NULL ;
				p_objstr_matched_begin_len = 0 ;
			}
			else
			{
				TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "  wbyte still unmatched" )
				p_objstr_matching += objstr_step_len ;
				p_sepstr_matching = sepstr_begin ;
			}
			
		}
	}
	
	return 0;
}

ZlangInvokeFunction ZlangInvokeFunction_Split_string;
int ZlangInvokeFunction_Split_string( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	struct ZlangObject			*in1 = GetInputParameterInLocalObjectStack(rt,1) ;
	struct ZlangObject			*out1 = GetOutputParameterInLocalObjectStack(rt,1) ;
	int					nret = 0 ;
	
	nret = string_Split_string_string( rt , obj , in1 , NULL , out1 ) ;
	if( nret < 0 )
	{
		return nret;
	}
	else if( nret > 0 )
	{
		UnreferObject( rt , out1 );
		return 0;
	}
	
	return 0;
}

ZlangInvokeFunction ZlangInvokeFunction_Split_string_string;
int ZlangInvokeFunction_Split_string_string( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	struct ZlangObject			*in1 = GetInputParameterInLocalObjectStack(rt,1) ;
	struct ZlangObject			*in2 = GetInputParameterInLocalObjectStack(rt,2) ;
	struct ZlangObject			*out1 = GetOutputParameterInLocalObjectStack(rt,1) ;
	int					nret = 0 ;
	
	nret = string_Split_string_string( rt , obj , in1 , in2 , out1 ) ;
	if( nret < 0 )
	{
		return nret;
	}
	else if( nret > 0 )
	{
		UnreferObject( rt , out1 );
		return 0;
	}
	
	return 0;
}

ZlangInvokeFunction ZlangInvokeFunction_string_ExpandEnvVariables;
int ZlangInvokeFunction_string_ExpandEnvVariables( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	struct ZlangDirectProperty_string	*obj_direct_prop = GetObjectDirectProperty(obj) ;
	struct ZlangObject			*out1 = GetOutputParameterInLocalObjectStack(rt,1) ;
	int					nret = 0 ;
	
	nret = ExpandEnvVariables( rt , obj_direct_prop ) ;
	if( nret )
	{
		TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "ExpandEnvVariables failed[%d]" , nret )
		CallRuntimeFunction_bool_SetBoolValue( rt , out1 , FALSE );
		return 0;
	}
	
	CallRuntimeFunction_bool_SetBoolValue( rt , out1 , TRUE );
	return 0;
}

ZlangCreateDirectPropertyFunction ZlangCreateDirectProperty_string;
void *ZlangCreateDirectProperty_string( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	struct ZlangDirectProperty_string	*obj_direct_prop = NULL ;
	int					nret = 0 ;
	
	obj_direct_prop = (struct ZlangDirectProperty_string *)ZLMALLOC( sizeof(struct ZlangDirectProperty_string) ) ;
	if( obj_direct_prop == NULL )
	{
		SET_RUNTIME_ERROR( rt , RUNTIME_ERROR , ZLANG_ERROR_ALLOC , "alloc memory for entity" )
		return NULL;
	}
	memset( obj_direct_prop , 0x00 , sizeof(struct ZlangDirectProperty_string) );
	
	nret = PrepareBuffer( rt , obj_direct_prop , 1 ) ;
	if( nret )
		return NULL;
	
	return (void *)obj_direct_prop;
}

ZlangDestroyDirectPropertyFunction ZlangDestroyDirectProperty_string;
void ZlangDestroyDirectProperty_string( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	struct ZlangDirectProperty_string	*obj_direct_prop = GetObjectDirectProperty(obj) ;
	
	if( obj_direct_prop->buf )
	{
		ZLFREE( obj_direct_prop->buf ); obj_direct_prop->buf = NULL ;
		obj_direct_prop->buf_size = 0 ;
	}

	ZLFREE( obj_direct_prop );
	
	return;
}

ZlangFromCharPtrFunction ZlangFromCharPtr_string;
int ZlangFromCharPtr_string( struct ZlangRuntime *rt , struct ZlangObject *obj , char *str , int32_t str_len )
{
	struct ZlangDirectProperty_string	*obj_direct_prop = GetObjectDirectProperty(obj) ;
	
	if( str == NULL )
	{
		if( obj_direct_prop->buf )
		{
			ZLFREE( obj_direct_prop->buf ); obj_direct_prop->buf = NULL ;
			obj_direct_prop->buf_size = 0 ;
		}
		
		return 0;
	}
	else if( str_len == -1 )
	{
		str_len = strlen(str) ;
	}
	else if( str_len < -1 )
	{
		return ZLANG_ERROR_INTERNAL;
	}
	
	if( obj_direct_prop->buf == NULL || str_len+1 > obj_direct_prop->buf_size )
	{
		int	new_buf_size ;
		char 	*new_buf = NULL ;
		
		new_buf_size = str_len+1 ;
		new_buf = (char*)ZLREALLOC( obj_direct_prop->buf , new_buf_size ) ;
		if( new_buf == NULL )
		{
			SET_RUNTIME_ERROR( rt , RUNTIME_ERROR , ZLANG_ERROR_REALLOC , "ZLREALLOC memory for string.buf" )
			return ZLANG_ERROR_ALLOC;
		}
		obj_direct_prop->buf = new_buf ;
		obj_direct_prop->buf_size = new_buf_size ;
	}
	
	if( str_len > 0 )
	{
		memmove( obj_direct_prop->buf , str , str_len );
	}
	obj_direct_prop->buf_len = str_len ;
	obj_direct_prop->buf[obj_direct_prop->buf_len] = '\0' ;
	
	return 0;
}

ZlangToStringFunction ZlangToString_string;
int ZlangToString_string( struct ZlangRuntime *rt , struct ZlangObject *obj , struct ZlangObject **tostr_obj )
{
	struct ZlangDirectProperty_string	*obj_direct_prop = GetObjectDirectProperty(obj) ;
	
	return ZlangFromCharPtr_string( rt , (*tostr_obj) , obj_direct_prop->buf , obj_direct_prop->buf_len );
}

ZlangFromDataPtrFunction ZlangFromDataPtr_string;
int ZlangFromDataPtr_string( struct ZlangRuntime *rt , struct ZlangObject *obj , void *value_ptr , int32_t value_len )
{
	return ZlangFromCharPtr_string( rt , obj , value_ptr , value_len );
}

ZlangGetDataPtrFunction ZlangGetDataPtr_string;
int ZlangGetDataPtr_string( struct ZlangRuntime *rt , struct ZlangObject *obj , void **value_ptr , int32_t *value_len )
{
	struct ZlangDirectProperty_string	*obj_direct_prop = GetObjectDirectProperty(obj) ;
	
	if( value_ptr )
		(*value_ptr) = obj_direct_prop->buf ;
	if( value_len )
		(*value_len) = obj_direct_prop->buf_len ;
	return 0;
}

ZlangOperatorFunction ZlangOperator_string_PLUS_string;
int ZlangOperator_string_PLUS_string( struct ZlangRuntime *rt , struct ZlangObject *in_obj1 , struct ZlangObject *in_obj2 , struct ZlangObject **out_obj )
{
	struct ZlangDirectProperty_string	*in1 = GetObjectDirectProperty(in_obj1) ;
	struct ZlangDirectProperty_string	*in2 = GetObjectDirectProperty(in_obj2) ;
	struct ZlangDirectProperty_string	*out = NULL ;
	int32_t					new_str_len ;
	int32_t					new_buf_size ;
	
	out = GetObjectDirectProperty(*out_obj) ;
	
	new_str_len = in1->buf_len + in2->buf_len ;
	new_buf_size = new_str_len + 1 ;
	
	if( out->buf == NULL || new_buf_size > out->buf_size )
	{
		char 	*new_buf = NULL ;
		
		new_buf = (char*)ZLREALLOC( out->buf , new_buf_size ) ;
		if( new_buf == NULL )
		{
			SET_RUNTIME_ERROR( rt , RUNTIME_ERROR , ZLANG_ERROR_REALLOC , "ZLREALLOC memory for string.buf" )
			return ZLANG_ERROR_ALLOC;
		}
		out->buf = new_buf ;
		out->buf_size = new_buf_size ;
	}
	
	memcpy( out->buf , in1->buf , in1->buf_len );
	memcpy( out->buf+in1->buf_len , in2->buf , in2->buf_len );
	out->buf[new_str_len] = '\0' ;
	out->buf_len = new_str_len ;
	
	return 0;
}

ZlangCompareFunction ZlangCompare_string_EGUAL_string;
int ZlangCompare_string_EGUAL_string( struct ZlangRuntime *rt , struct ZlangObject *in_obj1 , struct ZlangObject *in_obj2 , struct ZlangObject *out_obj )
{
	struct ZlangDirectProperty_string	*in1 = GetObjectDirectProperty(in_obj1) ;
	struct ZlangDirectProperty_string	*in2 = GetObjectDirectProperty(in_obj2) ;
	
	if( in1->buf && in2->buf && in1->buf_len == in2->buf_len )
	{
		if( memcmp( in1->buf , in2->buf , in1->buf_len ) == 0 )
		{
			TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "[%.*s]==[%.*s]=>[true]" , in1->buf_len,in1->buf , in2->buf_len,in2->buf )
			CallRuntimeFunction_bool_SetBoolValue( rt , out_obj , TRUE );
		}
		else
		{
			TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "[%.*s]==[%.*s]=>[false]" , in1->buf_len,in1->buf , in2->buf_len,in2->buf )
			CallRuntimeFunction_bool_SetBoolValue( rt , out_obj , FALSE );
		}
	}
	else
	{
		TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "[%.*s]==[%.*s]=>[false]" , in1->buf_len,in1->buf , in2->buf_len,in2->buf )
		CallRuntimeFunction_bool_SetBoolValue( rt , out_obj , FALSE );
	}
	
	return 0;
}

ZlangCompareFunction ZlangCompare_string_NOTEGUAL_string;
int ZlangCompare_string_NOTEGUAL_string( struct ZlangRuntime *rt , struct ZlangObject *in_obj1 , struct ZlangObject *in_obj2 , struct ZlangObject *out_obj )
{
	struct ZlangDirectProperty_string	*in1 = GetObjectDirectProperty(in_obj1) ;
	struct ZlangDirectProperty_string	*in2 = GetObjectDirectProperty(in_obj2) ;
	
	if( in1->buf && in2->buf && in1->buf_len == in2->buf_len )
	{
		if( memcmp( in1->buf , in2->buf , in1->buf_len ) == 0 )
		{
			TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "[%.*s]!=[%.*s]=>[false]" , in1->buf_len,in1->buf , in2->buf_len,in2->buf )
			CallRuntimeFunction_bool_SetBoolValue( rt , out_obj , FALSE );
		}
		else
		{
			TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "[%.*s]!=[%.*s]=>[true]" , in1->buf_len,in1->buf , in2->buf_len,in2->buf )
			CallRuntimeFunction_bool_SetBoolValue( rt , out_obj , TRUE );
		}
	}
	else
	{
		TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "[%.*s]!=[%.*s]=>[true]" , in1->buf_len,in1->buf , in2->buf_len,in2->buf )
		CallRuntimeFunction_bool_SetBoolValue( rt , out_obj , TRUE );
	}
	
	return 0;
}

ZlangCompareFunction ZlangCompare_string_LT_string;
int ZlangCompare_string_LT_string( struct ZlangRuntime *rt , struct ZlangObject *in_obj1 , struct ZlangObject *in_obj2 , struct ZlangObject *out_obj )
{
	struct ZlangDirectProperty_string	*in1 = GetObjectDirectProperty(in_obj1) ;
	struct ZlangDirectProperty_string	*in2 = GetObjectDirectProperty(in_obj2) ;
	int32_t					len ;
	int					nret = 0 ;
	
	len = MIN( in1->buf_len , in2->buf_len ) ;
	nret = memcmp( in1->buf , in2->buf , len ) ;
	if( nret < 0 )
	{
		CallRuntimeFunction_bool_SetBoolValue( rt , out_obj , TRUE );
	}
	else if( nret > 0 )
	{
		CallRuntimeFunction_bool_SetBoolValue( rt , out_obj , FALSE );
	}
	else
	{
		if( len == in1->buf_len )
		{
			if( len == in2->buf_len )
			{
				TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "[%.*s]<[%.*s]=>[false]" , in1->buf_len,in1->buf , in2->buf_len,in2->buf )
				CallRuntimeFunction_bool_SetBoolValue( rt , out_obj , FALSE );
			}
			else
			{
				TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "[%.*s]<[%.*s]=>[true]" , in1->buf_len,in1->buf , in2->buf_len,in2->buf )
				CallRuntimeFunction_bool_SetBoolValue( rt , out_obj , TRUE );
			}
		}
		else
		{
			TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "[%.*s]<[%.*s]=>[false]" , in1->buf_len,in1->buf , in2->buf_len,in2->buf )
			CallRuntimeFunction_bool_SetBoolValue( rt , out_obj , FALSE );
		}
	}
	
	return 0;
}

ZlangCompareFunction ZlangCompare_string_LE_string;
int ZlangCompare_string_LE_string( struct ZlangRuntime *rt , struct ZlangObject *in_obj1 , struct ZlangObject *in_obj2 , struct ZlangObject *out_obj )
{
	struct ZlangDirectProperty_string	*in1 = GetObjectDirectProperty(in_obj1) ;
	struct ZlangDirectProperty_string	*in2 = GetObjectDirectProperty(in_obj2) ;
	int32_t					len ;
	int					nret = 0 ;
	
	len = MIN( in1->buf_len , in2->buf_len ) ;
	nret = memcmp( in1->buf , in2->buf , len ) ;
	if( nret < 0 )
	{
		TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "[%.*s]<=[%.*s]=>[true]" , in1->buf_len,in1->buf , in2->buf_len,in2->buf )
		CallRuntimeFunction_bool_SetBoolValue( rt , out_obj , TRUE );
	}
	else if( nret > 0 )
	{
		TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "[%.*s]<=[%.*s]=>[false]" , in1->buf_len,in1->buf , in2->buf_len,in2->buf )
		CallRuntimeFunction_bool_SetBoolValue( rt , out_obj , FALSE );
	}
	else
	{
		if( len == in1->buf_len )
		{
			TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "[%.*s]<=[%.*s]=>[true]" , in1->buf_len,in1->buf , in2->buf_len,in2->buf )
			CallRuntimeFunction_bool_SetBoolValue( rt , out_obj , TRUE );
		}
		else
		{
			TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "[%.*s]<=[%.*s]=>[false]" , in1->buf_len,in1->buf , in2->buf_len,in2->buf )
			CallRuntimeFunction_bool_SetBoolValue( rt , out_obj , FALSE );
		}
	}
	
	return 0;
}

ZlangCompareFunction ZlangCompare_string_GT_string;
int ZlangCompare_string_GT_string( struct ZlangRuntime *rt , struct ZlangObject *in_obj1 , struct ZlangObject *in_obj2 , struct ZlangObject *out_obj )
{
	struct ZlangDirectProperty_string	*in1 = GetObjectDirectProperty(in_obj1) ;
	struct ZlangDirectProperty_string	*in2 = GetObjectDirectProperty(in_obj2) ;
	int32_t					len ;
	int					nret = 0 ;
	
	len = MIN( in1->buf_len , in2->buf_len ) ;
	nret = memcmp( in1->buf , in2->buf , len ) ;
	if( nret > 0 )
	{
		TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "[%.*s]>[%.*s]=>[true]" , in1->buf_len,in1->buf , in2->buf_len,in2->buf )
		CallRuntimeFunction_bool_SetBoolValue( rt , out_obj , TRUE );
	}
	else if( nret < 0 )
	{
		TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "[%.*s]>[%.*s]=>[false]" , in1->buf_len,in1->buf , in2->buf_len,in2->buf )
		CallRuntimeFunction_bool_SetBoolValue( rt , out_obj , FALSE );
	}
	else
	{
		if( len == in2->buf_len )
		{
			if( len == in1->buf_len )
			{
				TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "[%.*s]>[%.*s]=>[false]" , in1->buf_len,in1->buf , in2->buf_len,in2->buf )
				CallRuntimeFunction_bool_SetBoolValue( rt , out_obj , FALSE );
			}
			else
			{
				TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "[%.*s]>[%.*s]=>[true]" , in1->buf_len,in1->buf , in2->buf_len,in2->buf )
				CallRuntimeFunction_bool_SetBoolValue( rt , out_obj , TRUE );
			}
		}
		else
		{
			TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "[%.*s]>[%.*s]=>[false]" , in1->buf_len,in1->buf , in2->buf_len,in2->buf )
			CallRuntimeFunction_bool_SetBoolValue( rt , out_obj , FALSE );
		}
	}
	
	return 0;
}

ZlangCompareFunction ZlangCompare_string_GE_string;
int ZlangCompare_string_GE_string( struct ZlangRuntime *rt , struct ZlangObject *in_obj1 , struct ZlangObject *in_obj2 , struct ZlangObject *out_obj )
{
	struct ZlangDirectProperty_string	*in1 = GetObjectDirectProperty(in_obj1) ;
	struct ZlangDirectProperty_string	*in2 = GetObjectDirectProperty(in_obj2) ;
	int32_t					len ;
	int					nret = 0 ;
	
	len = MIN( in1->buf_len , in2->buf_len ) ;
	nret = memcmp( in1->buf , in2->buf , len ) ;
	if( nret > 0 )
	{
		TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "[%.*s]>=[%.*s]=>[true]" , in1->buf_len,in1->buf , in2->buf_len,in2->buf )
		CallRuntimeFunction_bool_SetBoolValue( rt , out_obj , TRUE );
	}
	else if( nret < 0 )
	{
		TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "[%.*s]>=[%.*s]=>[false]" , in1->buf_len,in1->buf , in2->buf_len,in2->buf )
		CallRuntimeFunction_bool_SetBoolValue( rt , out_obj , FALSE );
	}
	else
	{
		if( len == in2->buf_len )
		{
			TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "[%.*s]>=[%.*s]=>[true]" , in1->buf_len,in1->buf , in2->buf_len,in2->buf )
			CallRuntimeFunction_bool_SetBoolValue( rt , out_obj , TRUE );
		}
		else
		{
			TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "[%.*s]>=[%.*s]=>[false]" , in1->buf_len,in1->buf , in2->buf_len,in2->buf )
			CallRuntimeFunction_bool_SetBoolValue( rt , out_obj , FALSE );
		}
	}
	
	return 0;
}

ZlangSummarizeDirectPropertySizeFunction ZlangSummarizeDirectPropertySize_string;
void ZlangSummarizeDirectPropertySize_string( struct ZlangRuntime *rt , struct ZlangObject *obj , size_t *summarized_obj_size , size_t *summarized_direct_prop_size )
{
	struct ZlangDirectProperty_string	*direct_prop = GetObjectDirectProperty(obj) ;
	
	if( direct_prop->buf == NULL || direct_prop->buf_size <= 0 )
		SUMMARIZE_SIZE( summarized_direct_prop_size , sizeof(struct ZlangDirectProperty_string) )
	else
		SUMMARIZE_SIZE( summarized_direct_prop_size , sizeof(struct ZlangDirectProperty_string)+direct_prop->buf_size )
	
	return;
}

static struct ZlangDirectFunctions direct_funcs_string =
	{
		ZLANG_OBJECT_string ,
		
		ZlangCreateDirectProperty_string ,
		ZlangDestroyDirectProperty_string ,
		
		ZlangFromCharPtr_string ,
		ZlangToString_string ,
		ZlangFromDataPtr_string ,
		ZlangGetDataPtr_string ,
		
		ZlangOperator_string_PLUS_string ,
		NULL ,
		NULL ,
		NULL ,
		NULL ,
		
		NULL ,
		NULL ,
		NULL ,
		NULL ,
		NULL ,
		
		ZlangCompare_string_EGUAL_string ,
		ZlangCompare_string_NOTEGUAL_string ,
		ZlangCompare_string_LT_string ,
		ZlangCompare_string_LE_string ,
		ZlangCompare_string_GT_string ,
		ZlangCompare_string_GE_string ,
		
		NULL ,
		NULL ,
		
		NULL ,
		NULL ,
		NULL ,
		NULL ,
		NULL ,
		
		ZlangSummarizeDirectPropertySize_string ,
	} ;

ZlangDirectFunction_string_Clear string_Clear;
int string_Clear( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	return ZlangFromCharPtr_string( rt , obj , "" , 0 );
}

ZlangDirectFunction_string_PrepareBuffer string_PrepareBuffer;
int string_PrepareBuffer( struct ZlangRuntime *rt , struct ZlangObject *obj , int32_t prepare_len )
{
	struct ZlangDirectProperty_string	*obj_direct_prop = GetObjectDirectProperty(obj) ;
	
	return PrepareBuffer( rt , obj_direct_prop , prepare_len );
}

ZlangDirectFunction_string_GetDirectPropertiesPtr string_GetDirectPropertiesPtr;
int string_GetDirectPropertiesPtr( struct ZlangRuntime *rt , struct ZlangObject *obj , char ***buf , int32_t **buf_size , int32_t **buf_len )
{
	struct ZlangDirectProperty_string	*obj_direct_prop = GetObjectDirectProperty(obj) ;
	
	if( buf )
		(*buf) = & (obj_direct_prop->buf) ;
	if( buf_size )
		(*buf_size) = & (obj_direct_prop->buf_size) ;
	if( buf_len )
		(*buf_len) = & (obj_direct_prop->buf_len) ;
	return 0;
}

ZlangDirectFunction_string_SetStringValue string_SetStringValue;
int string_SetStringValue( struct ZlangRuntime *rt , struct ZlangObject *obj , char *value , int32_t value_len )
{
	if( ! IsTypeOf( rt , obj , GetStringObjectInRuntimeObjectsHeap(rt) ) )
		return ZLANG_ERROR_FUNC_PARAMETER_TYPE_NOT_MATCHED;
	
	ZlangFromCharPtr_string( rt , obj , value , value_len );
	
	return 0;
}

ZlangDirectFunction_string_FormatStringValue string_FormatStringValue;
int string_FormatStringValue( struct ZlangRuntime *rt , struct ZlangObject *obj , char *format , va_list valist )
{
	struct ZlangDirectProperty_string	*obj_direct_prop = GetObjectDirectProperty(obj) ;
	va_list					valist_prepare ;
	int32_t					prepare_len ;
	int					nret = 0 ;
	
	if( ! IsTypeOf( rt , obj , GetStringObjectInRuntimeObjectsHeap(rt) ) )
		return ZLANG_ERROR_FUNC_PARAMETER_TYPE_NOT_MATCHED;
	
	obj_direct_prop->buf_len = 0 ;
	
	va_copy( valist_prepare , valist );
	prepare_len = vsnprintf( NULL , 0 , format , valist_prepare ) ;
	nret = PrepareBuffer( rt , obj_direct_prop , prepare_len ) ;
	if( nret )
		return nret;
	
	obj_direct_prop->buf_len = vsnprintf( obj_direct_prop->buf , obj_direct_prop->buf_size , format , valist ) ;
	
	return 0;
}

ZlangDirectFunction_string_AppendStringValue string_AppendStringValue;
int string_AppendStringValue( struct ZlangRuntime *rt , struct ZlangObject *obj , char *value , int32_t value_len )
{
	struct ZlangDirectProperty_string	*obj_direct_prop = GetObjectDirectProperty(obj) ;
	int					nret = 0 ;
	
	if( ! IsTypeOf( rt , obj , GetStringObjectInRuntimeObjectsHeap(rt) ) )
		return ZLANG_ERROR_FUNC_PARAMETER_TYPE_NOT_MATCHED;
	
	nret = PrepareBuffer( rt , obj_direct_prop , value_len ) ;
	if( nret )
		return nret;
	
	memcpy( obj_direct_prop->buf+obj_direct_prop->buf_len , value , value_len ) ;
	obj_direct_prop->buf_len += value_len ;
	obj_direct_prop->buf[obj_direct_prop->buf_len] = '\0' ;
	
	return 0;
}

ZlangDirectFunction_string_AppendFormatStringValue string_AppendFormatStringValue;
int string_AppendFormatStringValue( struct ZlangRuntime *rt , struct ZlangObject *obj , char *format , va_list valist )
{
	struct ZlangDirectProperty_string	*obj_direct_prop = GetObjectDirectProperty(obj) ;
	va_list					valist_prepare ;
	int32_t					prepare_len ;
	int					nret = 0 ;
	
	if( ! IsTypeOf( rt , obj , GetStringObjectInRuntimeObjectsHeap(rt) ) )
		return ZLANG_ERROR_FUNC_PARAMETER_TYPE_NOT_MATCHED;
	
	va_copy( valist_prepare , valist );
	prepare_len = vsnprintf( NULL , 0 , format , valist_prepare ) ;
	nret = PrepareBuffer( rt , obj_direct_prop , prepare_len ) ;
	if( nret )
		return nret;
	
	obj_direct_prop->buf_len += vsnprintf( obj_direct_prop->buf+obj_direct_prop->buf_len , obj_direct_prop->buf_size-obj_direct_prop->buf_len , format , valist ) ;
	
	return 0;
}

ZlangDirectFunction_string_ExpandEnvVariables string_ExpandEnvVariables;
int string_ExpandEnvVariables( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	struct ZlangDirectProperty_string	*obj_direct_prop = GetObjectDirectProperty(obj) ;
	
	return ExpandEnvVariables( rt , obj_direct_prop );
}

ZlangDirectFunction_string_GetStringValue string_GetStringValue;
int string_GetStringValue( struct ZlangRuntime *rt , struct ZlangObject *obj , char **value , int32_t *value_len )
{
	if( ! IsTypeOf( rt , obj , GetStringObjectInRuntimeObjectsHeap(rt) ) )
		return ZLANG_ERROR_FUNC_PARAMETER_TYPE_NOT_MATCHED;
	
	if( IsObjectPropertiesEntityNull(obj) )
	{
		(*value) = NULL ;
	}
	else
	{
		char		*s = NULL ;
		int32_t		len ;
		ZlangGetDataPtr_string( rt , obj , (void**)&s , & len );
		s[len] = '\0' ;
		if( value )
			(*value) = s ;
		if( value_len )
			(*value_len) = len ;
	}
	return 0;
}

ZlangImportObjectFunction ZlangImportObject_string;
struct ZlangObject *ZlangImportObject_string( struct ZlangRuntime *rt )
{
	struct ZlangObject	*obj = NULL ;
	struct ZlangFunction	*func = NULL ;
	int			nret = 0 ;
	
	nret = ImportObject( rt , & obj , ZLANG_OBJECT_string , & direct_funcs_string , sizeof(struct ZlangDirectFunctions) , NULL ) ;
	if( nret )
	{
		SET_RUNTIME_ERROR( rt , RUNTIME_ERROR , ZLANG_ERROR_LINK_FUNC_TO_ENTITY , "import object to global objects heap" )
		return NULL;
	}
	
	/* string.Append(string) */
	func = AddFunctionAndParametersInObject( rt , obj , "Append" , "Append(string)" , ZlangInvokeFunction_string_Append_string , ZLANG_OBJECT_void , ZLANG_OBJECT_string,NULL , NULL ) ;
	if( func == NULL )
		return NULL;
	
#if 0
	/* string.CharAt(int) */
	func = AddFunctionAndParametersInObject( rt , obj , "CharAt" , "CharAt(int)" , ZlangInvokeFunction_string_CharAt_int , ZLANG_OBJECT_string , ZLANG_OBJECT_int,NULL , NULL ) ;
	if( func == NULL )
		return NULL;
#endif
	
	/* string.Delete(int,int) */
	func = AddFunctionAndParametersInObject( rt , obj , "Delete" , "Delete(int,int)" , ZlangInvokeFunction_string_Delete_int_int , ZLANG_OBJECT_void , ZLANG_OBJECT_int,NULL , ZLANG_OBJECT_int,NULL , NULL ) ;
	if( func == NULL )
		return NULL;
	
	/* string.EndWith(string) */
	func = AddFunctionAndParametersInObject( rt , obj , "EndWith" , "EndWith(string)" , ZlangInvokeFunction_string_EndWith_string , ZLANG_OBJECT_bool , ZLANG_OBJECT_string,NULL , NULL ) ;
	if( func == NULL )
		return NULL;
	
	/* string.EndCaseWith(string) */
	func = AddFunctionAndParametersInObject( rt , obj , "EndCaseWith" , "EndCaseWith(string)" , ZlangInvokeFunction_string_EndCaseWith_string , ZLANG_OBJECT_bool , ZLANG_OBJECT_string,NULL , NULL ) ;
	if( func == NULL )
		return NULL;
	
	/* string.EqualsIgnoreCase(string) */
	func = AddFunctionAndParametersInObject( rt , obj , "EqualsIgnoreCase" , "EqualsIgnoreCase(string)" , ZlangInvokeFunction_string_EqualsIgnoreCase_string , ZLANG_OBJECT_bool , ZLANG_OBJECT_string,NULL , NULL ) ;
	if( func == NULL )
		return NULL;
	
	/* string.Length() */
	func = AddFunctionAndParametersInObject( rt , obj , "Length" , "Length()" , ZlangInvokeFunction_string_Length , ZLANG_OBJECT_int , NULL ) ;
	if( func == NULL )
		return NULL;
	
	/* string.BufferSize() */
	func = AddFunctionAndParametersInObject( rt , obj , "BufferSize" , "BufferSize()" , ZlangInvokeFunction_string_BufferSize , ZLANG_OBJECT_int , NULL ) ;
	if( func == NULL )
		return NULL;
	
	/* string.Format(...) */
	func = AddFunctionAndParametersInObject( rt , obj , "Format" , "Format(...)" , ZlangInvokeFunction_string_Format_vargs , ZLANG_OBJECT_int , ZLANG_OBJECT_vargs,NULL , NULL ) ;
	if( func == NULL )
		return NULL;
	
	/* string.AppendFormat(...) */
	func = AddFunctionAndParametersInObject( rt , obj , "AppendFormat" , "AppendFormat(...)" , ZlangInvokeFunction_string_AppendFormat_vargs , ZLANG_OBJECT_int , ZLANG_OBJECT_vargs,NULL , NULL ) ;
	if( func == NULL )
		return NULL;
	
	/* string.FormatString(string) */
	func = AddFunctionAndParametersInObject( rt , obj , "FormatString" , "FormatString(string)" , ZlangInvokeFunction_string_FormatString_string , ZLANG_OBJECT_string , ZLANG_OBJECT_string,NULL , NULL ) ;
	if( func == NULL )
		return NULL;
	
	/* string.IndexOf(string) */
	func = AddFunctionAndParametersInObject( rt , obj , "IndexOf" , "IndexOf(string)" , ZlangInvokeFunction_string_IndexOf_string , ZLANG_OBJECT_int , ZLANG_OBJECT_string,NULL , NULL ) ;
	if( func == NULL )
		return NULL;
	
	/* string.IsNumeric() */
	func = AddFunctionAndParametersInObject( rt , obj , "IsNumeric" , "IsNumeric()" , ZlangInvokeFunction_string_IsNumeric , ZLANG_OBJECT_bool , NULL ) ;
	if( func == NULL )
		return NULL;
	
	/* string.IsAlphabetic() */
	func = AddFunctionAndParametersInObject( rt , obj , "IsAlphabetic" , "IsAlphabetic()" , ZlangInvokeFunction_string_IsAlphabetic , ZLANG_OBJECT_bool , NULL ) ;
	if( func == NULL )
		return NULL;
	
	/* string.IsNumericOrAlphabetic() */
	func = AddFunctionAndParametersInObject( rt , obj , "IsNumericOrAlphabetic" , "IsNumericOrAlphabetic()" , ZlangInvokeFunction_string_IsNumericOrAlphabetic , ZLANG_OBJECT_bool , NULL ) ;
	if( func == NULL )
		return NULL;
	
	/* string.Insert(int,string) */
	func = AddFunctionAndParametersInObject( rt , obj , "Insert" , "Insert(int,string)" , ZlangInvokeFunction_string_Insert_int_string , ZLANG_OBJECT_void , ZLANG_OBJECT_int,NULL , ZLANG_OBJECT_string,NULL , NULL ) ;
	if( func == NULL )
		return NULL;
	
	/* string.Replace(string,string) */
	func = AddFunctionAndParametersInObject( rt , obj , "Replace" , "Replace(string,string)" , ZlangInvokeFunction_string_Replace_string_string , ZLANG_OBJECT_void , ZLANG_OBJECT_string,NULL , ZLANG_OBJECT_string,NULL , NULL ) ;
	if( func == NULL )
		return NULL;
	
	/* string.ReplaceAll(string,string) */
	func = AddFunctionAndParametersInObject( rt , obj , "ReplaceAll" , "ReplaceAll(string,string)" , ZlangInvokeFunction_string_ReplaceAll_string_string , ZLANG_OBJECT_void , ZLANG_OBJECT_string,NULL , ZLANG_OBJECT_string,NULL , NULL ) ;
	if( func == NULL )
		return NULL;
	
	/* string.StartWith(string) */
	func = AddFunctionAndParametersInObject( rt , obj , "StartWith" , "StartWith(string)" , ZlangInvokeFunction_string_StartWith_string , ZLANG_OBJECT_bool , ZLANG_OBJECT_string,NULL , NULL ) ;
	if( func == NULL )
		return NULL;
	
	/* string.StartCaseWith(string) */
	func = AddFunctionAndParametersInObject( rt , obj , "StartCaseWith" , "StartCaseWith(string)" , ZlangInvokeFunction_string_StartCaseWith_string , ZLANG_OBJECT_bool , ZLANG_OBJECT_string,NULL , NULL ) ;
	if( func == NULL )
		return NULL;
	
	/* string.SubString(int,int) */
	func = AddFunctionAndParametersInObject( rt , obj , "SubString" , "SubString(int,int)" , ZlangInvokeFunction_string_SubString_int_int , ZLANG_OBJECT_string , ZLANG_OBJECT_int,NULL , ZLANG_OBJECT_int,NULL , NULL ) ;
	if( func == NULL )
		return NULL;
	
	/* string.ToShort() */
	func = AddFunctionAndParametersInObject( rt , obj , "ToShort" , "ToShort()" , ZlangInvokeFunction_string_ToShort , ZLANG_OBJECT_short , NULL ) ;
	if( func == NULL )
		return NULL;
	
	/* string.ToInt() */
	func = AddFunctionAndParametersInObject( rt , obj , "ToInt" , "ToInt()" , ZlangInvokeFunction_string_ToInt , ZLANG_OBJECT_int , NULL ) ;
	if( func == NULL )
		return NULL;
	
	/* string.ToLong() */
	func = AddFunctionAndParametersInObject( rt , obj , "ToLong" , "ToLong()" , ZlangInvokeFunction_string_ToLong , ZLANG_OBJECT_long , NULL ) ;
	if( func == NULL )
		return NULL;
	
	/* string.ToFloat() */
	func = AddFunctionAndParametersInObject( rt , obj , "ToFloat" , "ToFloat()" , ZlangInvokeFunction_string_ToFloat , ZLANG_OBJECT_float , NULL ) ;
	if( func == NULL )
		return NULL;
	
	/* string.ToDouble() */
	func = AddFunctionAndParametersInObject( rt , obj , "ToDouble" , "ToDouble()" , ZlangInvokeFunction_string_ToDouble , ZLANG_OBJECT_double , NULL ) ;
	if( func == NULL )
		return NULL;
	
	/* string.LowerCase() */
	func = AddFunctionAndParametersInObject( rt , obj , "LowerCase" , "LowerCase()" , ZlangInvokeFunction_string_LowerCase , ZLANG_OBJECT_void , NULL ) ;
	if( func == NULL )
		return NULL;
	
	/* string.UpperCase() */
	func = AddFunctionAndParametersInObject( rt , obj , "UpperCase" , "UpperCase()" , ZlangInvokeFunction_string_UpperCase , ZLANG_OBJECT_void , NULL ) ;
	if( func == NULL )
		return NULL;
	
	/* string.Trim() */
	func = AddFunctionAndParametersInObject( rt , obj , "Trim" , "Trim()" , ZlangInvokeFunction_string_Trim , ZLANG_OBJECT_void , NULL ) ;
	if( func == NULL )
		return NULL;
	
	/* string.RegexpMatch(string) */
	func = AddFunctionAndParametersInObject( rt , obj , "RegexpMatch" , "RegexpMatch(string)" , ZlangInvokeFunction_RegexpMatch_string , ZLANG_OBJECT_int , ZLANG_OBJECT_string,NULL , NULL ) ;
	if( func == NULL )
		return NULL;
	
	/* string.RegexpExtract(...) */
	func = AddFunctionAndParametersInObject( rt , obj , "RegexpExtract" , "RegexpExtract(...)" , ZlangInvokeFunction_RegexpExtract_vargs , ZLANG_OBJECT_int , ZLANG_OBJECT_vargs,NULL , NULL ) ;
	if( func == NULL )
		return NULL;
	
	/* string.RegexpReplace(string,string) */
	func = AddFunctionAndParametersInObject( rt , obj , "RegexpReplace" , "RegexpReplace(string,string)" , ZlangInvokeFunction_RegexpReplace_string_string , ZLANG_OBJECT_int , ZLANG_OBJECT_string,NULL , ZLANG_OBJECT_string,NULL , NULL ) ;
	if( func == NULL )
		return NULL;
	
	/* string.RegexpReplaceAll(string,string) */
	func = AddFunctionAndParametersInObject( rt , obj , "RegexpReplaceAll" , "RegexpReplaceAll(string,string)" , ZlangInvokeFunction_RegexpReplaceAll_string_string , ZLANG_OBJECT_int , ZLANG_OBJECT_string,NULL , ZLANG_OBJECT_string,NULL , NULL ) ;
	if( func == NULL )
		return NULL;
	
	/* string.RegexpRewrite(string,string) */
	func = AddFunctionAndParametersInObject( rt , obj , "RegexpRewrite" , "RegexpRewrite(string,string)" , ZlangInvokeFunction_RegexpRewrite_string_string , ZLANG_OBJECT_int , ZLANG_OBJECT_string,NULL , ZLANG_OBJECT_string,NULL , NULL ) ;
	if( func == NULL )
		return NULL;
	
	/* string.Split(string) */
	func = AddFunctionAndParametersInObject( rt , obj , "Split" , "Split(string)" , ZlangInvokeFunction_Split_string , ZLANG_OBJECT_array , ZLANG_OBJECT_string,NULL , NULL ) ;
	if( func == NULL )
		return NULL;
	
	/* string.Split(string,string) */
	func = AddFunctionAndParametersInObject( rt , obj , "Split" , "Split(string,string)" , ZlangInvokeFunction_Split_string_string , ZLANG_OBJECT_array , ZLANG_OBJECT_string,NULL , ZLANG_OBJECT_string,NULL , NULL ) ;
	if( func == NULL )
		return NULL;
	
	/* string.ExpandEnvVariables() */
	func = AddFunctionAndParametersInObject( rt , obj , "ExpandEnvVariables" , "ExpandEnvVariables()" , ZlangInvokeFunction_string_ExpandEnvVariables , ZLANG_OBJECT_bool , NULL ) ;
	if( func == NULL )
		return NULL;
	
	SetRuntimeFunction_string_AppendFormatFromArgsStack( rt , ZlangInvokeFunction_string_AppendFormat_vargs );
	SetRuntimeFunction_string_Clear( rt , string_Clear );
	SetRuntimeFunction_string_PrepareBuffer( rt , string_PrepareBuffer );
	SetRuntimeFunction_string_GetDirectPropertiesPtr( rt , string_GetDirectPropertiesPtr );
	SetRuntimeFunction_string_SetStringValue( rt , string_SetStringValue );
	SetRuntimeFunction_string_FormatStringValue( rt , string_FormatStringValue );
	SetRuntimeFunction_string_AppendStringValue( rt , string_AppendStringValue );
	SetRuntimeFunction_string_AppendFormatStringValue( rt , string_AppendFormatStringValue );
	SetRuntimeFunction_string_ExpandEnvVariables( rt , string_ExpandEnvVariables );
	SetRuntimeFunction_string_GetStringValue( rt , string_GetStringValue );
	
	return obj ;
}

